从R写入Excel时处理java.lang.OutOfMemoryError

从R写入Excel时处理java.lang.OutOfMemoryError,r,xlsx,R,Xlsx,xlsx包可用于从R读取和写入Excel电子表格。不幸的是,即使是中等规模的电子表格,也可能发生java.lang.OutOfMemoryError。特别是, .jcallRJavaTools,Ljava/lang/Object;中存在错误;,调用方法,cl,: java.lang.OutOfMemoryError:java堆空间 .jcallRJavaTools,Ljava/lang/Object;中存在错误;,新实例,.jfindClassclass,: java.lang.OutOfMem

xlsx包可用于从R读取和写入Excel电子表格。不幸的是,即使是中等规模的电子表格,也可能发生java.lang.OutOfMemoryError。特别是,

.jcallRJavaTools,Ljava/lang/Object;中存在错误;,调用方法,cl,: java.lang.OutOfMemoryError:java堆空间

.jcallRJavaTools,Ljava/lang/Object;中存在错误;,新实例,.jfindClassclass,: java.lang.OutOfMemoryError:超出GC开销限制

其他相关的例外情况也是可能的,但更为罕见

在阅读电子表格时,针对此错误也提出了类似的问题

<> P>使用Excel电子表格作为CSV上的数据存储介质的主要优点是可以在同一文件中存储多个表,因此,我们考虑每个工作表写入一个数据帧的数据帧列表。这个示例数据集包含40个数据帧,每个数据帧有两列,最多200k行。它的设计足够大,可能会出现问题,但您可以通过更改n_图纸和n_行来更改大小

在具有8GB RAM的机器上以64位运行此命令时,它会在第一次运行addDataFrame时抛出超出GC开销限制的错误

如何使用xlsx将大型数据集写入Excel电子表格?

这是一个已知问题:

虽然未解决,但问题页面建议在加载rJava包之前通过设置java.parameters选项来增加堆大小。rJava是xlsx的一个依赖项

值1000是允许Java堆的RAM兆字节数;它可以替换为您喜欢的任何值。我的实验表明,值越大越好,您可以愉快地使用您的全部RAM权限。例如,我使用以下方法获得了最佳结果:

options(java.parameters = "-Xmx8000m")
在具有8GB RAM的机器上

通过在循环的每次迭代中请求垃圾收集,可以获得进一步的改进。正如@gjabel所指出的,R垃圾收集可以使用执行。我们可以定义一个调用Java方法的Java垃圾收集函数:


在@richiecotton answer的基础上,我发现在jgc函数中添加gc可以降低CPU的使用率

jgc <- function()
{
  gc()
  .jcall("java/lang/System", method = "gc")
}    

我以前的for循环仍然与原来的jgc函数有冲突,但是使用额外的命令,我不再遇到GC开销限制超出错误消息。

如果您逐行写入,也可以在循环中使用GC。gc代表垃圾收集。gc可用于任何内存问题。

上述错误的解决方案: 请使用以下提到的r代码:

detach(package:xlsx)
detach(package:XLConnect)
library(openxlsx)

并且,再次尝试导入该文件,您不会得到任何错误,因为它对我有效

我在write.xlsx上遇到了问题,而不是阅读。。。。但后来意识到我无意中运行了32位R。将其换成64位已经解决了这个问题。

现在可以通过将xlsx包换成openxlsx包来避免整个问题,它依赖于Rcpp而不是Java。readxl是另一个看起来很有希望的新C/C++替代方案。不幸的是,我发现这两个都是检测和读取日期的垃圾,最终都陷入了无法纠正的混乱状态,即Excel日期格式:\@RichieCotton,不错的替代方案。但是,openxlsx无法读取.xls或.xlm文件!2007 excel file format.call options java.parameters=-Xmx8000m在加载rJava、xlsxjars、xlsx之前解决了.jcallRJavaTools、Ljava/lang/Object;中的错误;,invokeMethod,cl,:org.apache.poi.POIXMLException:java.lang.reflect.InvokeTargetException调用:getNetwork…->。jrcall->.jcall->.jcheck->.RHEL 6.3 x86_64、java 1.7.0_79 Oracle、rJava_0.9-7、xlsxjars_0.6.0、xlsx_0.5.7中暂停的调用执行两条注释:xlConnect有相同的问题。更重要的是,告诉某人使用不同的库并不能解决被引用库的问题。这里的目标是保持在xlsx包中。还有其他线程专门用于XLConnect。
options(java.parameters = "-Xmx8000m")
jgc <- function()
{
  .jcall("java/lang/System", method = "gc")
}    
for(i in seq_along(the_data))
{
  gc()
  jgc()
  message("Creating sheet", i)
  sheet <- createSheet(wb, sheetName = names(the_data)[i])
  message("Adding data frame", i)
  addDataFrame(the_data[[i]], sheet)
}
for(i in seq_along(the_data))
{
  message("Writing sheet", i)
  write.xlsx2(
    the_data[[i]], 
    "test.xlsx", 
    sheetName = names(the_data)[i], 
    append    = i > 1
  )
}
jgc <- function()
{
  gc()
  .jcall("java/lang/System", method = "gc")
}    
detach(package:xlsx)
detach(package:XLConnect)
library(openxlsx)