ChatGPT解决这个技术问题 Extra ChatGPT

使用 gc() 命令强制垃圾收集在 R 中运行

我定期草率地编程。好吧,我一直在草率地编程,但有时会以内存不足错误的形式赶上我。我开始练习使用 rm() 命令删除对象,事情变得更好了。我在网上看到关于在删除大型数据对象后是否应该显式调用 gc() 的混合消息。有人说在 R 返回内存错误之前它会运行 gc() 而其他人说手动强制 gc 是个好主意。

我是否应该在删除大对象后运行 gc() 以确保最大的内存可用性?


C
Community

“大概。”我也这样做,甚至经常在一个循环中

cleanMem <- function(n=10) { for (i in 1:n) gc() }

然而,根据我的经验,这并不能将记忆恢复到原始状态。

所以我通常做的是将手头的任务保存在脚本文件中,并使用'r'前端(在Unix上,并来自'littler'包)执行那些任务。 Rscript 是其他操作系统的替代方案。

该工作流程恰好同意

统计分析和报告撰写工作流程

管理会话中可用内存的技巧

我们之前在这里介绍过。


为什么重复运行 gc() 会有所帮助?
.@DirkEddelbuettel - 为什么要重复运行 gc()
是否有任何 R 支持的平台默认不附带 Rscript?我认为它是任何操作系统的替代方案,而不仅仅是“那个”操作系统。
Rscript 无处不在,更小,而 r 不是。这就是我更喜欢后者的上下文(但前者只是修复了一个重要的嘘声)。
R
Richie Cotton

gc 的帮助页面:

调用“gc”会导致垃圾收集发生。这也将在没有用户干预的情况下自动发生,调用“gc”的主要目的是报告内存使用情况。但是,在删除大对象后调用“gc”可能很有用,因为这可能会提示 R 将内存返回给操作系统。

所以它可以有用,但大多数情况下你不应该这样做。我个人的观点是,它是最后的代码——当然,您不应该在代码中乱扔 gc() 语句,但是如果您的机器不断摔倒,并且您已经尝试了其他所有方法,那么它可能有帮助。

其他一切,我的意思是像

编写函数而不是原始脚本,因此变量超出范围。如果您从一个问题转到另一个不相关的问题,则清空您的工作区。丢弃您不感兴趣的数据/变量。(我经常收到包含几十个无趣列的电子表格。)


在我的计算机中 gc() 释放了一些内存,但它并不完美。如果我加载一个大对象对它做一些事情,删除它并使用 gc() 并且我没有得到与开始时相同的可用内存。我做的事情越多,我无法恢复的记忆就越多。最后,在对大对象进行多次操作后,我可能会耗尽内存。我在 Windows 10 x64 中,我使用 16GB 的 RAM。
I
IRTFM

据说 R 只使用 RAM。这在 Mac 上不是这样(我怀疑在 Windows 上也不是这样。)如果它的 RAM 用完,它将开始使用虚拟内存。有时,但并非总是如此,进程会“认识到”它们需要运行 gc() 并释放内存。当他们不这样做时,您可以通过使用 ActivityMonitor.app 看到这一点,并看到所有 RAM 都已被占用,并且磁盘访问已跳升。我发现当我进行大型 Cox 回归运行时,我可以通过在调用之前使用 gc(); cph(...) 来避免溢出到虚拟内存(磁盘访问速度慢)


我可以确认 R 在 Windows 上不使用页面文件,有时它会非常有用。
T
Tommy

派对有点晚了,但是:

显式调用 gc 将“现在”释放一些内存。 ...所以如果 其他进程 需要内存,这可能是个好主意。例如在调用 system 或类似之前。或者,当您“完成”脚本时,R 将闲置一段时间,直到下一个作业到达 - 再次,以便 其他进程 获得更多内存。

如果你只是想让你的脚本运行得更快,那没关系,因为 R 会在需要时调用它。它甚至可能更慢,因为正常的 GC 周期可能永远不需要调用它。

...但是如果您想测量时间,通常最好在运行测试之前进行 GC。这是 system.time 默认执行的操作。

更新正如@DWin 指出的那样,R(或C#,或Java 等)并不总是知道何时内存不足并且GC 需要运行。因此,有时您可能需要执行 GC 作为内存系统缺陷的解决方法。


h
hadley

否。如果没有足够的内存可用于操作,R 将自动运行 gc()


根据我的经验,并不总是自动发生。如果您经常处理大数据,请定期 gc() 或重新启动您的 R 会话。
请为您的陈述提供证据。
> V1 <- 向量(长度=208000000) > sapply(1:20, function(x) {V2 <- 向量(长度=52000000); 0} ) [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 有 32 个警告(使用 warnings() 查看)> warnings() 警告消息:1:在向量中(长度 = 5.2e+07):已达到 1023Mb 的总分配:请参阅帮助( memory.size) ... 32 次 > V1 <- vector(length=208000000) > sapply(1:20, function(x) {V2 <- vector(length=52000000); rm(V2); gc(); 0} ) [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 >
这是一个固定的内存方案。如果你 rm() 和 gc(),你很好。你可以增加你的内存限制来避免这个问题,但是当周围有非常好的内存时,让 R 吃掉交换真的很烦人。
是否必须交换其他进程的内存页面才能为 R 提供必要的空间?因为根据我的经验,有时在中间步骤之后调用 gc() 以允许其他进程再次使用 RAM 会有所帮助,从而使计算机的响应速度比调用 gc() 之前要快得多。
S
Shane

“也许。”我真的没有一个确定的答案。但是帮助文件表明调用 gc() 的原因实际上只有两个:

您需要一份内存使用情况报告。删除大对象后,“它可能会提示 R 将内存返回给操作系统。”

由于重复调用会减慢大型模拟的速度,因此我倾向于仅在删除大型内容后才执行此操作。换句话说,除非你有充分的理由,否则我认为一直系统地调用它是没有意义的。