我正在处理一些大型数据集,并且正在尽我所能保持R的内存限制。关于覆盖R对象的一个问题。我有一个大的data.table
(或任何R对象),它必须多次复制到tmp
。问题是:如果我在覆盖之前删除tmp
会有什么不同吗?在代码中:
for (1:lots_of_times) {
v_l_d_t_tmp <- copy(very_large_data_table) # Necessary copy of 7GB data
# table on 16GB machine. I can
# afford 2 but not 3 copies.
### do stuff to v_l_d_t_tmp and output
rm (v_l_d_t_tmp) # The question is whether this rm keeps max memory
# usage lower, or if it is equivalent to what an
# overwrite will automatically do on the next iteration.
}
假设副本是必要的(如果我在每个循环中达到需要从磁盘读取very_large_data_table
的点,我会这样做,但问题是:它会对最大内存使用量产生任何影响吗?如果我再次加载之前明确删除v_l_d_t_tmp
?)。
或者,为了教导男人钓鱼,我可以输入什么(在R中,让我们不进入ps
)来回答这个问题?
如果答案结果是:“信任垃圾收集。”
答案 0 :(得分:2)
这是另一个想法......它没有直接回答你的问题,而是试图通过另一种方式消除内存问题来绕过它。可能会让你思考:
如果您改为缓存very_large_data_table,然后只读一次,执行您需要做的操作,然后退出R.现在,在R 之外写一个循环,然后记忆问题消失了。当然,这会花费你更多的CPU,因为你必须多次读取7GB ......但是可能值得节省内存成本。实际上,这会减少你的内存使用,因为你不必复制表。
另外,就像@konvas在评论中指出的那样,我也发现rm()
即使gc()
也没有得到我需要的长循环,内存会累积并最终陷入困境。退出R是一个简单的出路。
我经常这样做,所以我写了一个包来帮助我缓存这样的对象:simpleCache
如果你有兴趣尝试,它看起来像这样:
在R之外做这件事:
for (1:lots_of_times) {
Rscript my_script.R
}
然后在R中,执行此操作... my_script.R:
library(simpleCache)
simpleCache("very_large_data_table", {r code for how
you make this table }, assignTo="v_l_d_t_tmp")
### do stuff to v_l_d_t_tmp and output
答案 1 :(得分:1)
这是一个评论而不是一个答案,但它变得太长了。
我想在这种情况下,对rm
的调用可能是正确的。我认为从第二次迭代开始,如果你不打电话rm
,你可能在内存中有3个表。在复制大对象时,R无法在复制结束之前释放v_l_d_t_tmp
占用的内存,因为函数调用可能有错误,在这种情况下必须保留旧对象。考虑这个例子:
x<-1:10
myfunc<-function(y) {Sys.sleep(3);30}
这里我定义了一个对象和一个需要一些时间来做某事的函数。如果您尝试:
x<-myfunc()
并在结束之前中断执行&#34;当然&#34;,对象x
仍然存在,其1:10
内容。因此,我想在您的情况下,即使您使用相同的符号,R也无法在复制之前或期间释放其内容。如果您在以下副本之前删除它,它可以。当然,复制后将删除该对象,但在此期间可能会耗尽内存。
我绝不是R内幕的专家,所以不要理所当然地说我刚刚说的话。