测量R中的内存使用峰值

mqkwyuun  于 2023-06-19  发布在  其他
关注(0)|答案(3)|浏览(125)

我想在R中测量我的峰值内存使用量,以便我可以适当地分配资源。方法必须包含分析过程中创建的中间对象。例如,mx是在lapply的每个循环中创建的80Mb对象,但从未保存为全局变量。内存使用峰值应至少高于基线80Mb。

gc(reset = TRUE)
sum(gc()[, "(Mb)"]) # 172Mb

lapply(1:3, function(x) {
  mx <- rnorm(1e7) # 80Mb object
  mean(mx)
})

sum(gc()[, "(Mb)"]) # still 172Mb!
huwehgph

huwehgph1#

我在peakRAM包中找到了我要找的东西。关于documentation
这个软件包可以轻松地监视使用的总RAM和峰值RAM,以便开发人员可以快速识别和消除占用RAM的代码。

mem <- peakRAM({
  for(i in 1:5) {
    mean(rnorm(1e7))
  }
})
mem$Peak_RAM_Used_MiB # 10000486MiB
bhmjp9jg

bhmjp9jg2#

您可以使用gc函数来实现。
实际上,gc函数提供了字段11和12中使用的当前和最大内存(在文档中为Mb,但在我的机器上实际使用的是Mio)。您可以通过参数**reset=TRUE**重置最大值。下面是一个例子:

> gc(reset=TRUE)
         used (Mb) gc trigger   (Mb) max used (Mb)
Ncells 318687 17.1     654385   35.0   318687 17.1
Vcells 629952  4.9  397615688 3033.6   629952  4.9
> a = runif(1024*1024*64)  # Should request 512 Mio to the GC (on my machine)
> gc()
           used  (Mb) gc trigger   (Mb) max used  (Mb)
Ncells   318677  17.1     654385   35.0   318834  17.1
Vcells 67738785 516.9  318092551 2426.9 67739236 516.9
> memInfo <- gc()
> memInfo[11]              # Maximum Ncells
[1] 17.1
> memInfo[12]              # Maximum Vcells
[1] 516.9
> rm(a)                    # `a` can be removed by the GC from this point
> gc(reset=TRUE)           # Order to reset the GC infos including the maximum
         used (Mb) gc trigger   (Mb) max used (Mb)
Ncells 318858 17.1     654385   35.0   318858 17.1
Vcells 630322  4.9  162863387 1242.6   630322  4.9
> memInfo <- gc()
> memInfo[11]
[1] 17.1
> memInfo[12]              # The maximum has been correctly reset
[1] 4.9

在本例中,我们可以看到GC在runif调用周围的两个gc调用之间分配了最多516.9 - 4.9 = 512 Mb(这与预期结果一致)。

frebpwbc

frebpwbc3#

lapply返回的对象只有488个字节,因为它是总结的:垃圾收集在平均值计算后删除了中间对象。
help('Memory')给出了关于R如何管理内存的有用信息。
特别是,你可以使用object.size()来跟踪单个对象的大小,使用memory.size()来了解每一步总共使用了多少内存:

# With mean calculation
gc(reset = T)
#>          used (Mb) gc trigger (Mb) max used (Mb)
#> Ncells 405777 21.7     831300 44.4   405777 21.7
#> Vcells 730597  5.6    8388608 64.0   730597  5.6
sum(gc()[, "(Mb)"]) 
#> [1] 27.3

l<-lapply(1:3, function(x) {
  mx <- replicate(10, rnorm(1e6)) # 80Mb object
  mean(mx)
  print(paste('Memory used:',memory.size()))
})
#> [1] "Memory used: 271.04"
#> [1] "Memory used: 272.26"
#> [1] "Memory used: 272.26"

object.size(l)
#> 488 bytes

## Without mean calculation :
gc(reset = T)
#>          used (Mb) gc trigger  (Mb) max used (Mb)
#> Ncells 464759 24.9     831300  44.4   464759 24.9
#> Vcells 864034  6.6   29994700 228.9   864034  6.6
gcinfo(T)
#> [1] FALSE
sum(gc()[, "(Mb)"]) 
#> [1] 31.5
l<-lapply(1:4, function(x) {
  mx <- replicate(10, rnorm(1e6))
  print(paste('New object size:',object.size(mx)))
  print(paste('Memory used:',memory.size()))
  mx
})
#> [1] "New object size: 80000216"
#> [1] "Memory used: 272.27"
#> [1] "New object size: 80000216"
#> [1] "Memory used: 348.58"
#> [1] "New object size: 80000216"
#> [1] "Memory used: 424.89"
#> [1] "New object size: 80000216"
#> [1] "Memory used: 501.21"

object.size(l)
#> 320000944 bytes
sum(gc()[, "(Mb)"]) 
#> [1] 336.7

创建于2020-08-20由reprex package(v0.3.0)
如果不是返回mean,而是返回整个对象,则内存使用的增加是显著的。

相关问题