我定期草率地编程。好吧,我一直在草率地编程,但有时会以内存不足错误的形式赶上我。我开始练习使用 rm()
命令删除对象,事情变得更好了。我在网上看到关于在删除大型数据对象后是否应该显式调用 gc()
的混合消息。有人说在 R 返回内存错误之前它会运行 gc()
而其他人说手动强制 gc
是个好主意。
我是否应该在删除大对象后运行 gc()
以确保最大的内存可用性?
“大概。”我也这样做,甚至经常在一个循环中
cleanMem <- function(n=10) { for (i in 1:n) gc() }
然而,根据我的经验,这并不能将记忆恢复到原始状态。
所以我通常做的是将手头的任务保存在脚本文件中,并使用'r'前端(在Unix上,并来自'littler'包)执行那些任务。 Rscript 是其他操作系统的替代方案。
该工作流程恰好同意
统计分析和报告撰写工作流程
管理会话中可用内存的技巧
我们之前在这里介绍过。
从 gc
的帮助页面:
调用“gc”会导致垃圾收集发生。这也将在没有用户干预的情况下自动发生,调用“gc”的主要目的是报告内存使用情况。但是,在删除大对象后调用“gc”可能很有用,因为这可能会提示 R 将内存返回给操作系统。
所以它可以有用,但大多数情况下你不应该这样做。我个人的观点是,它是最后的代码——当然,您不应该在代码中乱扔 gc()
语句,但是如果您的机器不断摔倒,并且您已经尝试了其他所有方法,那么它可能有帮助。
其他一切,我的意思是像
编写函数而不是原始脚本,因此变量超出范围。如果您从一个问题转到另一个不相关的问题,则清空您的工作区。丢弃您不感兴趣的数据/变量。(我经常收到包含几十个无趣列的电子表格。)
据说 R 只使用 RAM。这在 Mac 上不是这样(我怀疑在 Windows 上也不是这样。)如果它的 RAM 用完,它将开始使用虚拟内存。有时,但并非总是如此,进程会“认识到”它们需要运行 gc() 并释放内存。当他们不这样做时,您可以通过使用 ActivityMonitor.app 看到这一点,并看到所有 RAM 都已被占用,并且磁盘访问已跳升。我发现当我进行大型 Cox 回归运行时,我可以通过在调用之前使用 gc(); cph(...)
来避免溢出到虚拟内存(磁盘访问速度慢)
派对有点晚了,但是:
显式调用 gc
将“现在”释放一些内存。 ...所以如果 其他进程 需要内存,这可能是个好主意。例如在调用 system
或类似之前。或者,当您“完成”脚本时,R 将闲置一段时间,直到下一个作业到达 - 再次,以便 其他进程 获得更多内存。
如果你只是想让你的脚本运行得更快,那没关系,因为 R 会在需要时调用它。它甚至可能更慢,因为正常的 GC 周期可能永远不需要调用它。
...但是如果您想测量时间,通常最好在运行测试之前进行 GC。这是 system.time
默认执行的操作。
更新正如@DWin 指出的那样,R(或C#,或Java 等)并不总是知道何时内存不足并且GC 需要运行。因此,有时您可能需要执行 GC 作为内存系统缺陷的解决方法。
否。如果没有足够的内存可用于操作,R 将自动运行 gc()
。
gc()
以允许其他进程再次使用 RAM 会有所帮助,从而使计算机的响应速度比调用 gc()
之前要快得多。
“也许。”我真的没有一个确定的答案。但是帮助文件表明调用 gc() 的原因实际上只有两个:
您需要一份内存使用情况报告。删除大对象后,“它可能会提示 R 将内存返回给操作系统。”
由于重复调用会减慢大型模拟的速度,因此我倾向于仅在删除大型内容后才执行此操作。换句话说,除非你有充分的理由,否则我认为一直系统地调用它是没有意义的。
不定期副业成功案例分享
gc()
会有所帮助?gc()
?Rscript
?我认为它是任何操作系统的替代方案,而不仅仅是“那个”操作系统。Rscript
无处不在,更小,而r
不是。这就是我更喜欢后者的上下文(但前者只是修复了一个重要的嘘声)。