R代码出现错误:"Error: cannot allocate buffer"。

3
在过夜编译一个 RMarkdown 脚本时,出现了以下错误消息:
“无法分配缓冲区 执行已停止”
代码块在训练一个 caretEnsemble 列表的 10 个机器学习算法时挂掉了。我知道需要大量的 RAM 和计算时间,但之前我曾在控制台中成功运行过同样的代码。为什么在 RMarkdown 中失败了?我非常确定即使它耗尽了可用的 RAM,也有足够的交换空间。
我使用带有 3GB RAM 和 4GB swap 的 Ubuntu。
我找到了一篇关于 R 中内存限制的博客文章,但它只适用于 Windows:http://www.r-bloggers.com/memory-limit-management-in-r/ 有什么解决或避免这个问题的办法吗?

2
你可以尝试将代码的那一部分提取出来(例如,将其放入另一个R脚本中)。不确定是否有效,但值得一试。如果这种方法行不通,你总可以单独运行它,使用save保存结果,然后在写作时加载它们。 - lmo
谢谢,我最终使用了 saveRDS。虽然它不是最优雅的解决方案,因为它没有检查缓存数据是否需要刷新,但现在它能够正常工作。将来我需要想办法更好地使用缓存/记忆化技术。 - adatum
2个回答

2
可能导致备份失败的原因之一是,knitr和Rmarkdown给事情增加了一层计算复杂性,并且它们需要一些内存。控制台是最简化的实现。
此外,Caret过于庞大、缓慢,而且不会为此道歉。如果机器学习算法很复杂,数据集很大,而且RAM有限,可能会出现问题。
一些减轻负担的方法:
1. 如果数据集中有未使用的变量,请使用您想要的变量子集,然后使用括号中的数据框变量名称在rm()中清除旧数据集的内存。
2. 删除变量后,运行垃圾回收,它会回收您删除的变量和临时集占用的内存空间。
R没有本地内存清除的方法,因此如果函数没有使用垃圾回收并且您没有这样做,所有以前执行的垃圾都会在内存中持续存在,使生活变得困难。只需在括号中输入gc()即可完成此操作。同时,在10次机器学习运行之间清除内存和gc()。如果使用XLConnect导入数据,则java实现非常低效...仅此就足以消耗您的内存,在每次使用gc()之后使用它。
3. 设置训练、测试和验证集后,将测试和验证文件以csv格式保存在硬盘上,并从内存中删除它们并运行gc()。在第一个模型之后再次加载它们。
4. 一旦您决定要运行哪些算法,请尝试单独安装其原始软件包而不是运行Caret,按名称逐个使用require()并使用detach(package:packagenamehere)清理每个软件包,然后使用gc()
这样做有两个原因:
第一,Caret是其他ML算法的集合,它本质上比它们所有原生环境下都慢。例如:我正在通过Caret运行数据集进行随机森林,在30分钟后,我还没有完成20%。在大约一小时标记处已经崩溃了两次。我加载了原始独立包,在大约4分钟内完成了分析。
第二,如果您需要、分离和垃圾回收,您需要更少的驻留内存来担心拖累您。否则,您同时拥有所有护理函数...这是浪费的。
有一些通用的事情可以使它变得更好,您可能最初不会想到,但可能会有用。根据您的代码,它们可能会或可能不会起作用,或者起作用的程度不同,但请尝试并查看它们可以为您带来什么。

I. 利用词法作用域。在一个干净的 Rstudio 环境中运行整个脚本,并确保所有部分都存在于您的工作空间中,然后清除垃圾。接下来去 knitr 和 rMarkdown,在已有的工作空间中调用这些部分。只要没有在循环内创建并保存到全局环境中,它就可以在 Markdown 下使用。

II. 在 markdown 中设置代码块,以缓存需要多次计算的内容,使它们准备好被调用,而不是多次消耗内存。

如果从数据框中调用变量,在一列中对每个观察值进行简单的乘法操作,并将其保存回原始的同一框架中,可能会产生多达 3 个内存副本。如果文件很大,那就非常占用资源。因此,制作一个干净的拷贝,清除垃圾并缓存纯框架。

直觉上,缓存似乎会浪费内存,并且如果处理不当,确实会浪费。但是,如果您定期从环境中删除不必要的变量并进行垃圾收集,则可能会从策略性缓存中受益。

III. 如果仍然存在性能问题,可以尝试将结果保存在 CSV 文件中并将其发送到硬盘上,根据需要调用它们,以将它们从内存中移出,如果您不需要所有数据。

我非常确定可以设置程序根据需要加载和卸载库、数据和结果。但是老实说,根据我的个人经验,对于大规模多算法处理,最好的方法是远离 Caret。


0

当我在64位机器上无意中运行32位版本的R时,我遇到了这个错误。


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