错误:java.lang.OutOfMemoryError:Java堆空间

47

我正在尝试将R连接到Teradata,以便直接从R中获取数据进行分析。但是,我遇到了以下错误:

Error in .jcall(rp, "I", "fetch", stride, block) :
  java.lang.OutOfMemoryError: Java heap space
我已经尝试通过以下方式设置我的 R 选项,以增加 JVM 的最大堆大小:

修改了如下设置:

options(java.parameters = "-Xmx8g")

我还尝试使用rJava函数.jinit来初始化Java参数,如下所示:.jinit(parameters="-Xmx8g")。但仍然失败了。

计算出的数据大小应该约为3G(实际上小于3G)。


你能否尝试使用更少的内存来验证它是否正常工作?仅仅因为原始数据只有3GB,并不排除JVM需要比这更多的内存的可能性。 - Tim Biegeleisen
6
在启动Java实例之前,请确保运行options(java.parameters = "-Xmx8g")。因此,请在没有加载任何软件包的新R会话中运行该命令,然后再加载所有软件包并重试。您应该可以正常运行,但是由于其他原因,JVM可能需要更多内存。 - stanekam
1
我猜“数据的计算大小”是指存储的有意义信息的大小。然而,数据结构在内存消耗方面并不理想——它们具有用于内部使用的字段,它们分配额外的内存以防止在添加数据时重复分配,因此即使是没有任何数据的空数据结构也会消耗一些内存。因此,3GB的数据很容易需要超过8GB的操作内存。 - user3707125
4个回答

42

14

我之前遇到了一个问题,但无法确定是什么原因导致的。我使用-Xmx8g解决了部分问题,但是现在问题却出现了随机性。

我现在找到了一个使用不同垃圾收集器的选项。

options(java.parameters = c("-XX:+UseConcMarkSweepGC", "-Xmx8192m"))
library(xlsx)

在脚本开始之前和加载任何其他包之前,因为其他包可能会自行加载一些Java内容,而选项必须在加载任何Java之前设置。

到目前为止,问题没有再次发生。

只有在长时间的会话中,有时仍然会出现此问题。但在这种情况下,会话重新启动通常可以解决问题。


1
是的。不知怎么的,这也使我的代码比以前运行得更快了。这确实是正确的答案。谢谢。 - Abdul Basit Khan
是的!谢谢您先生!在这里完美地运作了。 - Joao Fonseca

2
在Mac电脑上,在加载任何软件包之前运行以下两行代码即可:
options(java.parameters = c("-XX:+UseConcMarkSweepGC", "-Xmx8192m"))
gc()

这实际上结合了此前发布的两个建议: 重要的是,只运行第一行(如drmariod所建议的)在我的情况下并没有解决问题。然而,当我在第一行之后额外执行gc()时(如user2961057所建议的),问题就解决了。

如果仍然不起作用,请重新启动R会话,然后尝试(在加载任何软件包之前)使用options(java.parameters = "-Xmx8g"),然后直接在其后执行gc()。或者,尝试将RAM从"-Xmx8g"进一步增加到例如"-Xmx16g"(前提是您至少拥有同样多的RAM)。

编辑:进一步的解决方案:虽然我必须在R中使用rJava进行模型估计(解释大量的X),但即使我扩展到"-Xmx60000m"(我正在使用的机器有64 GB RAM),我仍然会收到上述“OutOfMemory”错误。问题在于某些模型规范实际上太大了(需要更多的RAM)。在这种情况下可能有助于缩小问题的规模(例如通过减少模型中的X数量),或者如果可能的话,将问题分成独立的部分,分别估计,然后再将这些部分组合在一起。


gc() 经常被我使用,为我解决了这个问题。谢谢! - Gildas

1
我添加了垃圾回收,这解决了我的问题。我使用RJDBC连接Oracle数据库。
只需添加gc()即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接