在R中跟踪内存使用和垃圾收集

时间:2011-06-10 20:53:13

标签: r memory garbage-collection

我正在运行深度嵌套的函数,并且消耗了Windows任务管理器报告的相当多的内存。输出变量相对较小(比消耗的内存量小1-2个数量级),所以我假设差异可以归因于在函数中某处分配的中间变量(或在被调用的子函数内)和垃圾收集延迟。所以,我的问题是:

1)我的假设是否正确?为什么或者为什么不?

2)简单地嵌入对函数的调用而不是分配中间变量是否有任何意义?这会减少内存使用吗?

3)假设一个场景,其中R在具有4GB RAM的系统上使用3GB内存。运行gc()后,它现在只使用2GB。在这种情况下,R是否足够智能自行运行垃圾收集,如果我曾经说过另一个耗尽了1.5GB内存的功能?

我正在使用的某些数据集能够在处理系统时因内存耗尽而导致系统崩溃,而我正在尝试缓解此问题。提前感谢您的任何答案!

约什

2 个答案:

答案 0 :(得分:6)

1)用于表示R中的对象的内存和由OS标记为正在使用的内存由多个层分隔(R自己的内存处理,OS何时以及如何从应用程序中回收内存等)。我会说(a)我不确定但是(b)有时任务管理器的内存使用概念可能无法准确反映R实际使用的内存,但是(c)是的,可能是你的差异describe描述了R为当前会话中的对象分配的内存。

2)在像

这样的功能中
f = function() { a = 1; g=function() a; g() }

调用f()打印1,暗示a使用的内存在调用g时仍被标记为正在使用。因此嵌套函数对内存管理没有帮助,可能相反。

最好的办法是在进行更大规模的分配之前清理或重复使用代表大量分配的变量。适当设计的功能可以帮助解决这个问题,例如,

f = function() { m = matrix(0, 10000, 10000); 1 }
g = function() { m = matrix(0, 10000, 10000); 1 }
h = function() { f(); g() }

f返回时不再需要f的大内存,如果g所需的大内存需要这样做,则可用于垃圾回收。

3)如果R尝试为变量分配内存而不能,则它将运行其垃圾收集器a并再次尝试。所以你自己运行gc()就无法获得任何收益。

我确保你已经编写了内存有效的代码,如果还有问题,我会转移到64位平台,在那里内存不是问题。

答案 1 :(得分:5)

R具有内存分析功能,但需要构建它。虽然我们为Debian / Ubuntu启用了这个功能,但我不知道Windows的默认设置是什么。

在“Writing R Extensions”手册中(简要)讨论了内存概要分析的使用。

在32位系统(尤其是Windows)上处理(有限的)内存存在挑战。大多数人会建议您切换到运行64位操作系统的RAM尽可能多的系统。