是否可以监视正在使用或已被R用于调用函数的内存量?例如,我有一个任意函数,例如:
smallest.sv <- function(){
A <- matrix(rnorm(1e6), 1e3);
mysvd <- svd(A);
return(tail(mysvd$d, 1));
}
Run Code Online (Sandbox Code Playgroud)
运行该函数只返回一个标量,但是使用了大量的内存来计算函数.现在我需要进行性能基准测试.处理时间很简单:
system.time(x <- smallest.sv())
Run Code Online (Sandbox Code Playgroud)
但是我还想知道这个调用需要多少内存,而不需要修改函数(它应该适用于任意函数).有没有办法做到这一点?
编辑:澄清一下.我最感兴趣的是在函数调用期间使用的内存上限,即需要多少物理内存才能处理函数调用.在许多情况下,这远远低于我认为的分配内存总量.
Dir*_*tel 20
R提供内存分析支持,请参阅Writing R Extensions手册的第3.3节:
3.3分析内存使用的R代码
当代码占用的内存多于方便可用的内存或者内存分配和对象复制负责慢代码时,在R代码中测量内存使用是很有用的.在R代码中,有三种方法可以分析内存使用情况.所有三个都需要使用`--enable-memory-profiling'编译R,这不是默认值,但目前用于Mac OS X和Windows二进制发行版.由于不同的原因,所有这些都可能会产生误导.
在了解内存配置文件时,了解一下R的内存分配是很有用的.查看`gc()'的结果显示将内存划分为用于存储向量内容的"Vcells"和用于存储其他所有内容的"Ncells",包括类型和长度信息等向量的所有管理开销.实际上,矢量内容分为两个池.用于小向量的存储器(默认为128字节或更少)以大块获得,然后由R分配出来; 用于较大向量的存储器直接从操作系统获得.
然后再提供三个部分.
Ryo*_*ogi 12
一种选择是使用Rprof.一个简单的方法是:
Rprof(tf <- "rprof.log", memory.profiling=TRUE)
[your code]
Rprof(NULL)
summaryRprof(tf)
Run Code Online (Sandbox Code Playgroud)
这将为您提供有关内存使用情况的一些信息.
您可以使用以下命令获取在处理函数和命令期间使用的内存上限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)
Run Code Online (Sandbox Code Playgroud)
该上限受到垃圾收集的影响,因此打开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
Run Code Online (Sandbox Code Playgroud)
其他工具如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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这里我得到的值比从 得到的值更高gc,这表明内存使用量受到垃圾收集的影响,并且在函数处理期间使用的内存上限可能因调用而异,只要gctorture不是打开。