意外的R内存管理行为

时间:2018-02-24 15:11:02

标签: r memory memory-management memory-leaks promise

我花了几天的时间在我编写的R程序中搜索我认为是内存泄漏的内容。事实证明这是由一些我真正掌握的R功能引起的。我的预感是它与承诺和懒惰评估有关。以下是重现问题的示例:

M <- matrix(rnorm(1E7), 1000)
format(object.size(M), "Mb") ## An 80 Mbs matrix
gc() ## Memory usage should be around 80 Mbs
LF <- apply(M, 1, function(X) {sdX <- sd(X); function(X) X / sdX})
format(object.size(LF), "Mb") ## 2.9 Mb (isn't it a lot for a few functions? but it's not really the point)
gc() ## Memory usage is at 158 Mbs event though our workspace only contains two objects of 80 and 2.9 Mbs
rm(M)
gc() ## Back to around 80 Mbs but M is gone
rm(LF)
gc() ## Back to normal

如果我们经常重复操作,您可以看到内存使用量会增长。 似乎R需要存储整个矩阵才能调用LF中的函数。关于在LF中创建函数时会发生什么的任何见解?解决方法?

1 个答案:

答案 0 :(得分:1)

您返回的函数的封闭环境是传递给apply的函数的本地环境。显然,函数参数必须存储在此环境中。通常这个环境在调用后会丢失,但是因为返回一个闭包而保留它。您可以删除不需要的对象:

LF <- apply(M, 1, function(X) {sdX <- sd(X); rm("X"); function(X) X / sdX})
ls(envir = environment(LF[[1]]))
#[1] "sdX"

但是,我仍然没有看到使用闭包的原因,并建议重新设计整个方法。例如,在这个具体的例子中,我将返回标准差并将它们作为参数传递给转换函数。