ChatGPT解决这个技术问题 Extra ChatGPT

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

我使用对 rm(list=ls()) 的调用定期清理 R 中的内存。
之后我需要调用垃圾收集器 gc() 吗?

这两个功能有什么区别? gc() 是否为某些变量调用 rm()


C
Community

首先,重要的是要注意这两者非常不同,因为 gc 不会删除您仍在使用的 任何 变量 - 它只会为您不再有权访问的变量释放内存to(无论是使用 rm() 删除,还是说,在一个已经返回的函数中创建)。运行 gc() 永远不会让您丢失变量。

不过,在调用 rm() 之后是否应该调用 gc() 的问题是一个很好的问题。 gc 的 documentation 有用地指出:

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

所以答案是调用 gc() 可能会很好(至少不会造成伤害),即使它可能无论如何都会被触发(如果不是马上,那么很快)。


谢谢您的回答。一般来说,R自动垃圾收集是否被认为是好的? (例如,与 java 的一样健壮)
这是一个很难回答的问题,我不确定。 This question 很有用。
一般来说,您不必调用 gc,如果您这样做,也不太可能有太大的不同。
@hadley 这与我的经验完全不符。相反,即使在大对象(大约几百 MiB)不再可用后,R 也经常导致我的操作系统进行交换。但是,手动调用 gc() 可以避免这种情况。使用可用内存是可以的,不必要的交换确实不行,因为它会对操作系统的可用性产生负面影响。最先进的 GC 可以更好地处理这个问题。
支持@KonradRudolph 的评论——在最近的一些工作中,我注意到函数的局部变量消耗了大量内存。当变量超出范围时,不会释放内存,就像在其他语言中一样。我不得不打电话给 gc()
G
Gabriel123

我个人喜欢在循环中包含 gc() 以在循环开始填满可用空间时释放一些 RAM。就像是

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

请注意,调用 gc() 会带来巨大的性能损失,每次调用大约 100 毫秒。因此,在这种情况下,您的代码将比必要的运行时间长约 100 秒 :)
P
Pascoe

ReThankGoat 对 gc 惩罚的评论,虽然这是真的,但当然可以决定在循环中每 N 次迭代调用 gc(其中 N 可以通过多种方式进行参数化)。对于迭代次数很大但给定迭代内的资源使用量较小的循环,可能没有必要在每次迭代中都进行 GC 以重新获得所需的性能。

当然,如果您正在循环使用大量非常高使用率的迭代,那就另当别论了,但在那个阶段,很可能只需要对代码进行矢量化和/或什至用另一种语言编写.