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

JD *_*ong 64 garbage-collection r

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

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

Dir*_*tel 46

"大概." 我也这样做,甚至经常在循环中

cleanMem <- function(n=10) { for (i in 1:n) gc() }
Run Code Online (Sandbox Code Playgroud)

然而,根据我的经验,这并没有将记忆恢复到原始状态.

所以我通常做的是将任务放在脚本文件中并使用'r'前端(在Unix上和'littler'包中)执行.Rscript是其他操作系统的替代品.

该工作流程恰好符合

我们之前介绍过的.

  • 为什么重复运行`gc()`有帮助? (41认同)
  • 是否有任何 R 支持的平台默认不随“Rscript”一起提供?我认为它是任何操作系统上的替代方案,而不仅仅是“那个”操作系统。 (2认同)

Ric*_*ton 23

从帮助页面gc:

调用'gc'会导致垃圾收集.这也将在没有用户干预的情况下自动进行,调用'gc'的主要目的是报告内存使用情况.

但是,在删除大对象后调用'gc'会很有用,因为这可能会提示R将内存返回给操作系统.

因此,它可以是做有用的,但主要是你不应该.我的个人意见是,它是最后的代码 - 你当然不应该用gc()语句乱扔你的代码,但如果你的机器不断摔倒,而你已经尝试了其他所有东西,那么它可能会有所帮助.

其他一切,我的意思是

  1. 编写函数而不是原始脚本,因此变量超出范围.

  2. 如果您从一个问题转到另一个不相关的问题,请清空您的工作区.

  3. 丢弃您不感兴趣的数据/变量.(我经常收到包含数十个不感兴趣的列的电子表格.)

  • 在我的电脑中,gc()释放了一些内存,但它并不完美.如果我加载一个大对象用它做一些事情,删除它并使用gc()并且我没有获得与开头相同的可用内存.我做的事情越多,我就无法恢复更多的记忆.最后,在使用大型对象进行多次操作后,我可能会耗尽内存.我在Windows 10 x64中使用16GB内存. (6认同)

Tom*_*mmy 14

派对有点晚了,但是:

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

如果您只是希望您的脚本运行得更快,那么无关紧要,因为如果需要,R会稍后调用它.它甚至可能更慢,因为正常的GC循环可能永远不需要调用它.

...但是如果你想测量时间,那么在运行测试之前进行GC通常是一个好主意.这是system.time默认情况下的做法.

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


42-*_*42- 14

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


had*_*ley 9

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

  • > V1 < - vector(length = 208000000)> sapply(1:20,function(x){V2 < - vector(length = 52000000); 0})[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0有32个警告(使用警告()查看)>警告()警告消息:1:向量(长度= 5.2e + 07):达到1023Mb的总分配:请参阅帮助( memory.size)... 32次> V1 < - vector(长度= 208000000)> sapply(1:20,函数(x){V2 < - vector(长度= 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> (7认同)
  • 这是一个固定的内存方案.如果你是rm()和gc(),你没事.你可以增加你的内存限制以避免这个问题,但是当有完美的RAM存在时,让R吃掉交换真的很烦人. (6认同)
  • 在我的经历中并不总是自动发生.如果您经常使用大数据,gc()定期或重新启动R会话. (4认同)

Sha*_*ane 7

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

  1. 您想要一份内存使用情况报告.
  2. 删除大对象后,"它可能会提示R将内存返回给操作系统".

因为它可以通过重复调用来减慢大型模拟,所以我倾向于只在删除大的东西之后才这样做.换句话说,除非你有充分的理由,否则我认为系统地一直调用它是没有意义的.