代码之家  ›  专栏  ›  技术社区  ›  eaglefreeman

意外的R内存管理行为

  •  3
  • eaglefreeman  · 技术社区  · 7 年前

    在过去的几天里,我一直在寻找我所写的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 回复  |  直到 7 年前
        1
  •  1
  •   Roland    7 年前

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

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

    然而,我仍然没有看到使用闭包的理由,建议重新设计整个方法。E、 在这个具体的例子中,我将返回标准偏差,并将其作为参数传递给变换函数。

    推荐文章