【问题标题】:R memory management - increasing memory consumptionR内存管理 - 增加内存消耗
【发布时间】:2013-03-24 11:32:05
【问题描述】:

我的代码如下(和原来相比稍微简化了一点,但还是反映了问题)。

require(VGAM)

Median.sum  = vector(mode="numeric", length=75) 
AA.sum      = vector(mode="numeric", length=75)                                                    
BB.sum      = vector(mode="numeric", length=75)                   
Median      = array(0, dim=c(75 ,3)) 
AA          = array(0, dim=c(75 ,3))                                                    
BB          = array(0, dim=c(75 ,3))                              

y.sum     = vector(mode="numeric", length=100000)
y         = array(0, dim=c(100000,3))
b.size    = vector(mode="numeric", length=3) 
c.size    = vector(mode="numeric", length=3) 


for (h in 1:40)
{
  for (j in 1:75)
  {  
    for (i in 1:100000)
    {
      y.sum[i] = 0

      for (f in 1:3)
      {
        b.size[f] = rbinom(1, 30, 0.9)
        c.size[f] = 30 - rbinom(1, 30, 0.9) + 1
        y[i, f] = sum( rlnorm(b.size[f], 8.5, 1.9) ) + 
          sum( rgpd(c.size[f], 120000, 1870000, 0.158) )
        y.sum[i] = y.sum[i] + y[i, f]
      }
    }

    Median.sum[j] = median(y.sum)
    AA.sum[j] = mean(y.sum)
    BB.sum[j] = quantile(y.sum, probs=0.85)

    for (f in 1:3)
    {
      Median[j,f] = median(y[,f])
      AA[j,f] = mean(y[,f])
      BB[j,f] = quantile(y[,f], probs=0.85)
    }
  }
  #gc()
}

它在执行过程中中断(h=7,j=1,i=93065)并出现错误:

Error: cannot allocate vector of size 526.2 Mb

收到此消息后,我已经阅读了thisthisthis,但还不够。问题是,垃圾收集器 (gc()) 和清除工作区中的所有对象都没有帮助。我的意思是我已经尝试将我的代码都放入我的代码:垃圾收集器和操作删除所有变量并在循环中再次声明它们(看看 #gc() 所在的位置 - 但是后者不包括在内在我发布的代码中)。

这对我来说似乎很奇怪,因为所有过程在循环的每个步骤中都使用相同的对象(=> 并且应该在循环的每个步骤中消耗相同的内存量)。为什么内存消耗会随着时间的推移而增加?

更糟糕的是,如果我想在 R 的同一会话中工作甚至执行:

rm(list=ls())
gc()

即使我想声明一些次要的内容,我仍然会收到相同的错误消息:

abc = array(0, dim=c(10,3))

只有关闭 R 并开始新会话才有帮助。为什么?也许有一些方法可以重新编码我的循环?

R:2.15.1(32 位),操作系统:Windows XP(32 位)

我在这里很新,所以每一个提示都值得赞赏!提前致谢。


编辑:(来自 Arun)。我发现仅通过一个简单的示例就可以更轻松地重现此行为。启动一个新的 R 会话并复制并粘贴此代码,然后在系统监视器中观察内存增长

mm <- rep(0, 1e4) # initialise a vector
for (i in 1:1e3) {
    for (j in 1:1e3) {
        for (k in 1:1e4) {
            mm[k] <- k # already pre-allocated
         }
    }
}

【问题讨论】:

  • rgpd 来自哪里?内存使用量随着时间的推移而增加,因为您的 y.sum 越来越大。
  • @Roman: rgpd 从广义帕累托分布中抽取随机值。 y.sum 真的在增长吗?它在代码的最开头声明。
  • 哦,我没有看到你的代码的顶部。您已经预先分配了您的对象。我把它收回。哼。
  • @brunner Very bluntly, “术语 32 位和 64 位是指计算机处理器(也称为 CPU)处理信息的方式。64 位版本的Windows 比 32 位系统更有效地处理大量随机存取内存 (RAM)"
  • 我可以通过@Arun 的示例重现问题。我在带有 RStudio 的 Linux 上使用 R 2.15.3 64bit。可以观察到进程rstudio的逐步内存跳转:170M, 194M, 224M, 259M, 301M, 347M, 408M, ...

标签: r memory-management nested-loops


【解决方案1】:

for (i in 1:100000) 循环中添加对gc() 的调用。

在 Arun 代码的紧密循环中添加对 gc() 的调用可以消除其内存增长。

这显示了内存增长:

mm <- rep(0, 1e4) # initialise a vector
for (i in 1:1e3) {
    for (j in 1:1e3) {
        for (k in 1:1e4) {
            mm[k] <- k # already pre-allocated
         }
     }
 }

这不是:

mm <- rep(0, 1e4) # initialise a vector
for (i in 1:1e3) {
    for (j in 1:1e3) {
        for (k in 1:1e4) {
            mm[k] <- k # already pre-allocated
            gc()
         }
     }
 }

这里的自动垃圾回收有些问题。如gcinfo(TRUE) 所示,在第一种情况下调用收集器。但是内存增长很快。

【讨论】:

  • 我只是在测试同样的东西,这似乎有效,但它没有回答为什么自动垃圾收集在这里不起作用的问题?另外,如果你第一次运行没有gc()的代码一段时间,然后运行第二个代码,它仍然不会删除之前代码中保留的内存。
  • @Matthew:谢谢,我会尝试将 gc() 放在“非常中间”的循环中。我会让你知道结果。但仍然 - Hemmo 是对的。
  • 它也不应该对 Arun 的代码产生影响,但确实如此。
  • @Matthew:可能你是对的,但是在将 gc() 放在“非常中间”的循环之后,这个过程非常耗时,完全没用。
【解决方案2】:

这似乎可行(将最内层循环放入函数中)。我直到最后都没有运行它,因为它很慢,但我没有注意到你的代码中的内存膨胀。

require(VGAM)

Median.sum  = vector(mode="numeric", length=75) 
AA.sum      = vector(mode="numeric", length=75)                                                    
BB.sum      = vector(mode="numeric", length=75)                   
Median      = array(0, dim=c(75 ,3)) 
AA          = array(0, dim=c(75 ,3))                                                    
BB          = array(0, dim=c(75 ,3))                              


inner.fun <- function() {
  y.sum     = vector(mode="numeric", length=100000)
  y         = array(0, dim=c(100000,3))
  b.size    = vector(mode="numeric", length=3) 
  c.size    = vector(mode="numeric", length=3) 
  for (i in 1:100000)
    {
      y.sum[i] = 0

      for (f in 1:3)
      {
        b.size[f] = rbinom(1, 30, 0.9)
        c.size[f] = 30 - rbinom(1, 30, 0.9) + 1
        y[i, f] = sum( rlnorm(b.size[f], 8.5, 1.9) ) + 
          sum( rgpd(c.size[f], 120000, 1870000, 0.158) )
        y.sum[i] = y.sum[i] + y[i, f]
      }
    }
    list(y.sum, y)
}

for (h in 1:40)
{
  cat("\nh =", h,"; j = ")
  for (j in 1:75)
  {  
    cat(j," ")
    result = inner.fun()
    y.sum = result[[1]]
    y = result[[2]]
    Median.sum[j] = median(y.sum)
    AA.sum[j] = mean(y.sum)
    BB.sum[j] = quantile(y.sum, probs=0.85)

    for (f in 1:3)
    {
      Median[j,f] = median(y[,f])
      AA[j,f] = mean(y[,f])
      BB[j,f] = quantile(y[,f], probs=0.85)
    }
  }
}

【讨论】:

    猜你喜欢
    • 2016-09-24
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 2015-01-04
    相关资源
    最近更新 更多