gc() 和 rm() 有什么区别?

92

我通过调用 rm(list=ls()) 定期清理 R 中的内存。
这之后,我需要调用垃圾回收器 gc() 吗?

这两个函数有什么区别?gc() 是否会针对某些变量调用 rm()

3个回答

122

首先,需要注意的是这两者非常不同。使用gc时并不会删除你仍在使用的任何变量,它只释放那些你无法访问到的内存(无论是使用rm()移除的还是在函数中创建后已经被返回)。运行gc()永远不会使你丢失变量。

然而,在调用rm()之后是否应该调用gc()是一个很好的问题。gc的文档非常有帮助地指出:

调用gc将导致进行垃圾回收。这也会自动进行而无需用户干预,调用gc的主要目的是报告内存使用情况。

然而,在删除大型对象后调用gc可能会有所帮助,因为这可能会促使R将内存返回给操作系统。

因此,答案是可以调用gc()(至少不会有坏处),即使它可能很快就会被触发(如果不是立即触发,那么很快也会触发)。


谢谢您的回答。一般来说,R语言自动垃圾回收被认为是好的吗?(例如像Java那样健壮) - RockScience
这是一个很难回答的问题,我不确定。这个问题很有用。这个问题是有用的。 - David Robinson
7
通常情况下,您不需要调用垃圾回收(gc),即使您这样做也不大可能有太大的影响。 - hadley
25
这与我的经验完全不符。相反,即使大对象(约几百 MiB)不再存在,R 通常会导致我的操作系统进行交换。然而,手动调用 gc() 可以避免这种情况。使用可用内存是可以的,但是不必要的交换会对操作系统的可用性产生负面影响。现代垃圾回收机制处理这个问题更好。 - Konrad Rudolph
6
同意 @KonradRudolph 的评论 - 在我最近的一些工作中,我注意到某个函数的本地变量消耗了大量内存。与其他语言不同的是,当这些变量超出作用域后,内存并未被释放。我不得不调用 gc() 函数。 - Paul
3
对于今天遇到这个问题并阅读此答案的人,我刚刚从我的环境中删除了一些变量 - 它们占用了约15GB的内存 - 但是R仍然无法存储任何进一步的变量,尽管我已经删除了不再需要的大型变量。然后我运行了gc(),等了一分钟,然后发现所有的内存都被重新分配给了我的会话,因此我又可以保存变量了。我想重申gc文档中的内容:...在删除大对象后调用gc可能很有用... - Mus

2
感谢ThankGoat在gc惩罚方面的评论,尽管这是真的,但人们当然可以决定在循环中每N次迭代调用gc(其中N可以以多种方式参数化)。 对于迭代次数较多但给定迭代内资源使用较为适度的循环,可能不需要每次迭代都进行GC以恢复所需的性能。
当然,如果您正在进行具有非常高使用率迭代次数的循环,则情况就不同了,但此时可能需要将代码简单向量化并/或甚至使用另一种语言编写。

2

个人喜欢在循环中包含gc()以释放一些RAM,当循环开始填充可用空间时。像这样:

for(i in 1:1000){
res[[i]] = some operation
gc()
}

27
请注意,调用gc()会带来大约100毫秒的巨大性能损失。因此,在这种情况下,您的代码将比必要的多运行大约100秒 :) - ThankGoat

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