监视 R 中的内存使用情况
Posted
技术标签:
【中文标题】监视 R 中的内存使用情况【英文标题】:Monitor memory usage in R 【发布时间】:2011-10-21 23:21:08 【问题描述】:是否可以监视 R 调用函数正在使用或已使用的内存量?例如,我有一个任意函数,例如:
smallest.sv <- function()
A <- matrix(rnorm(1e6), 1e3);
mysvd <- svd(A);
return(tail(mysvd$d, 1));
运行该函数只返回一个标量,但计算该函数会占用大量内存。现在我需要进行性能基准测试。处理时间很容易:
system.time(x <- smallest.sv())
但是我也想知道这个调用需要多少内存,而不修改函数(它应该适用于任意函数)。有没有办法做到这一点?
编辑:澄清一下。我最感兴趣的是函数调用期间使用的内存上限,即需要多少物理内存才能处理函数调用。在许多情况下,这比我认为的分配内存总量要少得多。
【问题讨论】:
嗨,杰罗恩。你解决了这个问题吗?你的解决方案是什么?我也面临这个问题。我希望监控函数调用期间使用的内存上限。 看看 profvis:github.com/rstudio/profvis 谢谢,杰森。我之前确实检查过。但在我看来,包仅用于分析代码使用的时间。我没有看到内存监控的功能。我在这里错过了什么吗?或者你能给我更多的提示吗? 另请参阅关于分析 R 中已编译代码的内存使用情况的讨论:***.com/questions/58278838/… 【参考方案1】:R 提供内存分析支持,请参阅Section 3.3 of the Writing R Extensions manual:
3.3 为内存使用分析 R 代码
在 R 代码中测量内存使用情况在代码占用 比方便使用或内存分配时更多的内存 对象的复制是导致代码缓慢的原因。有三种 在 R 代码中随时间分析内存使用情况的方法。这三个都需要 R 已使用 `--enable-memory-profiling' 编译,这不是 默认值,但目前用于 Mac OS X 和 Windows 二进制文件 分布。由于不同的原因,所有这些都可能具有误导性。
在了解内存配置文件时,了解一点很有用 更多关于 R 的内存分配。查看 `gc()' 的结果 将内存划分为“Vcells”,用于存储 向量和“Ncells”用于存储其他所有内容,包括所有 类型和长度等向量的管理开销 信息。实际上,向量内容分为两个池。 小向量的内存(默认为 128 字节或更少)在 大块,然后由 R 分块;较大向量的内存是 直接从操作系统获取。
然后再提供三个部分。
【讨论】:
【参考方案2】:一种选择是使用Rprof
。一个简单的方法是这样的:
Rprof(tf <- "rprof.log", memory.profiling=TRUE)
[your code]
Rprof(NULL)
summaryRprof(tf)
这将为您提供有关内存使用情况的一些信息。
【讨论】:
谢谢,这很有用。但是,据我了解, Rprofmem 记录了所有分配的内存,但它没有考虑到抓取收集?我最感兴趣的是函数处理过程中使用的内存上限。 您可以使用操作系统的性能监视器。操作前取读卡器,操作后取读卡器。在 Windows 上是 perfmon【参考方案3】:您可以通过gc
获得处理函数和命令期间正在使用的内存的上限:
smallest.sv <- function()
A <- matrix(rnorm(1e6), 1e3);
mysvd <- svd(A);
return(tail(mysvd$d, 1));
tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
x <- smallest.sv()
sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
#62 MB
rm(x)
这个上限受到垃圾回收的影响,因此打开gctorture
将给出下限:
tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
gctorture(on = TRUE)
x <- smallest.sv()
gctorture(on = FALSE)
sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
#53.7 MB
Rprof
、Rprofmem
、profmem::profmem
、bench::mark
或 profvis::profvis
等其他工具也可以显示内存使用情况。
#Using Rprof (Enable profiling is a compile-time option: ./configure --enable-R-profiling)
gc()
Rprof("Rprof.out", memory.profiling=TRUE)
x <- smallest.sv()
Rprof(NULL)
max(summaryRprof("Rprof.out", memory="both")$by.total$mem.total)
#45.9
#Here at defined intervals the status is checked and so the result depends on if you hit the peak
#Using Rprofmem (Enable momory profiling is a compile-time option: ./configure --enable-memory-profiling)
Rprofmem("Rprofmem.out"); x <- smallest.sv(); Rprofmem(NULL) #Wen first run, there is much more in the log file
gc()
Rprofmem("Rprofmem.out")
x <- smallest.sv()
Rprofmem(NULL)
sum(as.numeric(read.table("Rprofmem.out", comment.char = ":")[,1]), na.rm=TRUE)
#88101752
#Writes out them memory amount when it is allocated
library(profmem) #uses utils::Rprofmem
gc()
total(profmem(x <- smallest.sv()))
#88101752
library(bench) #uses utils::Rprofmem
gc()
mark(x <- smallest.sv())[,"mem_alloc"]
#84MB
#Warning message:
#Some expressions had a GC in every iteration; so filtering is disabled.
library(profvis) #uses utils::Rprof
gc()
profvis(x <- smallest.sv())
#opens a browser window where you can read under Memory -23.0 | 45.9
Rprofmem
显示的是累积分配的内存,不考虑执行期间释放的内存。要增加Rprof
达到峰值的概率,您可以选择较短的时间间隔或/并重复该过程。
max(replicate(10,
gc()
Rprof("Rprof.out", memory.profiling=TRUE, interval = runif(1,.005,0.02))
x <- smallest.sv()
Rprof(NULL)
max(summaryRprof("Rprof.out", memory="both")$by.total$mem.total)
))
#76.4
这里我得到的值比我从gc
得到的值高,这表明内存使用受垃圾收集和函数处理期间使用的内存上限的影响 em> 只要 gctorture
未打开,每次通话可能会有所不同。
【讨论】:
【参考方案4】:您可以使用PeakRAM
获得处理时间和峰值内存:
library(peakRAM)
peakRAM(smallest.sv())
Function_Call Elapsed_Time_sec Total_RAM_Used_MiB Peak_RAM_Used_MiB
1 smallest.sv() 3.64 0 61.1
【讨论】:
以上是关于监视 R 中的内存使用情况的主要内容,如果未能解决你的问题,请参考以下文章
通过Performance Monitor观察程序内存使用情况