R 中具有相同数据的相同操作的不可预测的内存使用
unpredictable memory usage by same operations with same data in R
我遇到一个问题,即 R 函数 (NbCluster) 使 R 崩溃,但在具有相同数据的不同 运行 上的不同点。根据 journalctl 的说法,崩溃都是因为内存问题。例如:
Sep 04 02:00:56 Q35 kernel: [ 7608] 1000 7608 11071962 10836497 87408640 0 0 rsession
Sep 04 02:00:56 Q35 kernel: Out of memory: Kill process 7608 (rsession) score 655 or sacrifice child
Sep 04 02:00:56 Q35 kernel: Killed process 7608 (rsession) total-vm:44287848kB, anon-rss:43345988kB, file-rss:0kB, shmem-rss:0kB
Sep 04 02:00:56 Q35 kernel: oom_reaper: reaped process 7608 (rsession), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
我一直在测试我的代码,以确定是哪些行导致了内存错误,结果发现它会有所不同,即使使用相同的数据也是如此。除了想解决它之外,我对为什么这是一个间歇性问题感到困惑。如果一个对象太大而无法放入内存,那么每次我 运行 给它相同的资源应该是个问题,对吧?
其他进程使用的内存量在 运行 之间没有显着差异,而且我总是从干净的环境开始。当我查看 top
时,我总是有空闲的内存(尽管我很少查看崩溃的确切时刻)。我尝试通过删除不需要的对象和定期垃圾收集来减少内存负载,但这没有明显的效果。
例如,当运行ning NbClust时,有时会在运行ning时发生崩溃
length(eigen(TT)$value)
其他时候它发生在 hclust
的调用期间。有时它不会崩溃并以相对优雅的方式退出 "cannot allocate vector size"
除了有关减少内存负载的任何建议外,我想知道为什么我有时 运行 内存不足,而其他时候却没有。
编辑:将 hclust
的所有用途更改为 hclust.vector
后,我在层次聚类步骤中没有再发生任何崩溃。然而,在不同的地方仍然会发生崩溃(通常是在 eigen()
的调用期间)。
如果我能够可靠地预测(在误差范围内)我的代码的每一行将使用多少内存,那就太好了。
现代内存管理远没有您想象的那么确定。
如果您想要更多可重现的结果,请确保摆脱任何垃圾收集、任何并行性(特别是垃圾收集 运行 与您的程序并行!)并确保该过程受限于内存的值远低于您的 free 系统内存。
内核 OOM 杀手是当内核过度使用内存(您可能想了解这意味着什么)、交换存储完全用完并且无法履行其承诺时的最后手段。
内核可以分配在首次访问之前不需要存在的内存。因此,OOM 杀手可能不会在分配时发生,而是在实际使用页面时发生。
我遇到一个问题,即 R 函数 (NbCluster) 使 R 崩溃,但在具有相同数据的不同 运行 上的不同点。根据 journalctl 的说法,崩溃都是因为内存问题。例如:
Sep 04 02:00:56 Q35 kernel: [ 7608] 1000 7608 11071962 10836497 87408640 0 0 rsession
Sep 04 02:00:56 Q35 kernel: Out of memory: Kill process 7608 (rsession) score 655 or sacrifice child
Sep 04 02:00:56 Q35 kernel: Killed process 7608 (rsession) total-vm:44287848kB, anon-rss:43345988kB, file-rss:0kB, shmem-rss:0kB
Sep 04 02:00:56 Q35 kernel: oom_reaper: reaped process 7608 (rsession), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
我一直在测试我的代码,以确定是哪些行导致了内存错误,结果发现它会有所不同,即使使用相同的数据也是如此。除了想解决它之外,我对为什么这是一个间歇性问题感到困惑。如果一个对象太大而无法放入内存,那么每次我 运行 给它相同的资源应该是个问题,对吧?
其他进程使用的内存量在 运行 之间没有显着差异,而且我总是从干净的环境开始。当我查看 top
时,我总是有空闲的内存(尽管我很少查看崩溃的确切时刻)。我尝试通过删除不需要的对象和定期垃圾收集来减少内存负载,但这没有明显的效果。
例如,当运行ning NbClust时,有时会在运行ning时发生崩溃
length(eigen(TT)$value)
其他时候它发生在 hclust
的调用期间。有时它不会崩溃并以相对优雅的方式退出 "cannot allocate vector size"
除了有关减少内存负载的任何建议外,我想知道为什么我有时 运行 内存不足,而其他时候却没有。
编辑:将 hclust
的所有用途更改为 hclust.vector
后,我在层次聚类步骤中没有再发生任何崩溃。然而,在不同的地方仍然会发生崩溃(通常是在 eigen()
的调用期间)。
如果我能够可靠地预测(在误差范围内)我的代码的每一行将使用多少内存,那就太好了。
现代内存管理远没有您想象的那么确定。
如果您想要更多可重现的结果,请确保摆脱任何垃圾收集、任何并行性(特别是垃圾收集 运行 与您的程序并行!)并确保该过程受限于内存的值远低于您的 free 系统内存。
内核 OOM 杀手是当内核过度使用内存(您可能想了解这意味着什么)、交换存储完全用完并且无法履行其承诺时的最后手段。
内核可以分配在首次访问之前不需要存在的内存。因此,OOM 杀手可能不会在分配时发生,而是在实际使用页面时发生。