TMS*_*TMS 6 r memory-profiling
我正在尝试使用分析来查看我的代码的哪一部分负责最大使用 3GB 内存(如gc()最大使用内存统计报告所示,请参阅此处如何)。我正在运行这样的内存分析:
Rprof(line.profiling = TRUE, memory.profiling = TRUE)
graf(...) # ... here I run the profiled code
Rprof(NULL)
summaryRprof(lines = "both", memory = "both")
Run Code Online (Sandbox Code Playgroud)
输出如下:
$by.total
total.time total.pct mem.total self.time self.pct
"graf" 299.12 99.69 50814.4 0.02 0.01
#2 299.12 99.69 50814.4 0.00 0.00
"graf.fit.laplace" 299.06 99.67 50787.2 0.00 0.00
"doTryCatch" 103.42 34.47 4339.2 0.00 0.00
"chol" 103.42 34.47 4339.2 0.00 0.00
"tryCatch" 103.42 34.47 4339.2 0.00 0.00
"tryCatchList" 103.42 34.47 4339.2 0.00 0.00
"tryCatchOne" 103.42 34.47 4339.2 0.00 0.00
"chol.default" 101.62 33.87 1087.0 101.62 33.87
graf.fit.laplace.R#46 85.80 28.60 3633.2 0.00 0.00
"backsolve" 78.82 26.27 1635.2 58.40 19.46
Run Code Online (Sandbox Code Playgroud)
我该如何解读呢mem.total?它是什么以及它的单位是什么?我尝试查看文档,即?Rprof和?summaryRprof,但似乎没有很好的记录:-/
编辑: 这里他们说 Rprof“定期探测 R 的总内存使用情况”。但这不适合 50GB,这远远超出了我的内存所能容纳的范围!(现在 8GB 物理 + 12GB 页面文件)。
同样,正如 R Yoda 所指出的,?summaryRprof内存=“两者”意味着“总内存的变化”。但它到底是什么(是总内存还是总内存的变化),以及它如何与 50GB 数字相匹配?
编辑:进行相同的分析profvis- 当我将鼠标悬停在 50812 上时,它显示“内存分配 (MB)”,并将鼠标悬停在靠近垂直线“峰值内存分配和释放的百分比”的黑色条上。不确定这意味着什么...这就像 50 GB,这意味着这可能是所有分配的总和 (??) ...绝对不是峰值内存使用量:
?summaryRprof说:
如果内存 =“两者”,则列表相同,但除了计时之外还具有以 Mb 为单位的内存消耗。
mem.totalMB 也是如此
当内存=“两者”时,报告总内存的变化(截断为零)[...]
您有 8 GB RAM + 12 GB 交换空间,但mem.total声称您已使用 50 GB?
因为它是两个后续探测之间的聚合增量(按Rprof固定时间间隔获取的内存使用情况快照:如果在函数 f 中执行时获取探测,则最后一个探测的内存使用增量将添加到mem.totalf 中)。
内存使用增量可能是负值,但我从未见过负值mem.total,所以我猜测(!)只有正值被添加到mem.total.
这可以解释您所看到的 50 GB 总使用量:它不是单个时间点内分配的内存量,而是整个执行时间内聚合的内存增量。
这也解释了仅显示 3 GB 作为“最大使用 (Mb)”的事实gc:内存被分配和释放/释放多次,这样您就不会遇到内存压力,但这会花费大量时间(移动如此多的数据) RAM 中的所有缓存都会失效,因此速度很慢),除了 CPU 应用的计算逻辑之外。
这个摘要(恕我直言)似乎还隐藏了这样一个事实:垃圾收集器(gc)在不确定的时间点启动以清理释放的内存。
由于 gc 开始是惰性的(非确定性的),恕我直言,将负内存增量归因于刚刚探测的单个函数是不公平的。
我认为mem.total这mem.total.used.during.runtime可能是该专栏的更好标签。
profvis有更详细的内存使用情况摘要(正如您在问题的屏幕截图中看到的那样):它还聚合了负内存使用增量(释放的内存),但 profvis 文档还警告了缺点:
代码面板还显示内存分配和释放。解释此信息可能有点棘手,因为它不一定反映该行代码中分配和释放的内存。采样分析器记录有关前一个样本和当前样本之间发生的内存分配的信息。这意味着该行上的分配/释放值可能实际上发生在前一行代码中。
更详细的答案将需要更多的研究时间(我没有) - 研究 C 和 R 源代码 - 理解(复制)summaryRprof基于创建的数据文件的聚合逻辑Rprof
Rprof数据文件 ( Rprof.out) 如下所示:
:376447:6176258:30587312:152:1#2 "test" 1#1 "test2"
Run Code Online (Sandbox Code Playgroud)
前四个数字(用冒号分隔)表示(请参阅?summaryRprof) - R_SmallVallocSize:R 堆上小块中的向量内存 [桶数] - R_LargeVallocSize:大块中的向量内存 [桶数](来自 malloc) - R 堆上节点中的内存 -duplicate时间间隔内对内部函数的调用次数(用于复制向量,例如在函数参数的首次写入时复制语义的情况下)
字符串是函数调用堆栈。
只有前两个数字与计算当前(向量)内存使用量(以 MB 为单位)相关:
TotalBuckets = R_SmallVallocSize + R_LargeVallocSize
mem.used = TotalBuckets * 8 Bytes / 1024 / 1024
# 50 MB in the above `Rprof` probe line:
# (376447 + 6176258) * 8 / 1024 / 1024
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请Vcells参阅?Memory。
顺便说一句:我想尝试summaryRProf(memory = "stats", diff = F)获取当前内存摘要,但我在 Ubuntu 上收到 R3.4.4 64 位的错误消息:
Error in tapply(seq_len(1L), list(index = c("1::#File", "\"test2\":1#1", :
arguments must have same length
Run Code Online (Sandbox Code Playgroud)
你能重现这个(看起来“统计”已损坏)吗?
| 归档时间: |
|
| 查看次数: |
1163 次 |
| 最近记录: |