ele*_*end 6 java memory-management r heap-memory
我正在使用R中的一些建模算法,其中一个在Java(bartMachine)中运行.我发现在运行建模算法之前,我需要根据数据的大小增加java的最大堆空间.
我这样做是这样的:
options(java.parameters = "-Xmx16g")
我的问题是,如果没有其他算法将使用java(或至少那么多堆空间),我是否需要重置堆空间?或者根据需要回收分配给java的内存而不会丢失性能?
我已经搜索了一些关于这个主题的内容,我了解如何更改/降低堆空间.我也明白R/Java会做垃圾收集来从内存中删除旧对象以释放更多空间.
我不明白的是,更改堆空间会如何影响其他程序可用的内存,以及在这种情况下是否有必要甚至是一个好主意来改变使用后的堆大小.
我已经看过的一些答案/资源:
http://www.bramschoenmakers.nl/en/node/726
https://cran.r-project.org/web/packages/bartMachine/bartMachine.pdf
它的实现是定义的,取决于由很多参数影响的实现.垃圾收集器可以影响它.在使用Oracles JVM 1.7的Mac上,它默认为并行收集器,-XX:+UseParallelGC并且此收集器不会将内存释放回操作系统.我在Mac上尝试了它并没有释放任何东西,只是使用-XX:+UseG1GC了.您可以使用以下内容查看默认版本:
java -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -version
Run Code Online (Sandbox Code Playgroud)
如果您正在使用支持它的JVM和正确的垃圾收集器,则可以使用一些参数来调整内存的释放方式,即
-XX:MinHeapFreeRatio (default is 40)
-XX:MaxHeapFreeRatio (default is 70)
Run Code Online (Sandbox Code Playgroud)
但它们被击中和错过(JVM决定何时释放内存,只释放大量对象可能不会触发它).
我最近使用了非常重的Java程序,感受到了你的痛苦.
我不能告诉你是否根据一个不可否认的技术事实重置动态分配的内存,但我的个人经验告诉我,如果你要在Java工作后继续在本机R环境中进行处理,你可能应该这样做.最好控制你的能力.
原因如下:
我曾经用完JVM(甚至使用MASSIVE平面文件)的唯一时间就是我以某种方式使用JVM.它不是一次性的事情,经常发生.
甚至只是通过Java驱动的XLConnect读取和编写大型excel文件; 记忆越来越快地卡住了.这似乎是R和Java相互竞争的方式的失败.
并且,r不会按照您希望的方式自动进行垃圾收集.它会在OS请求更多内存时收集,但事情可能会在此之前很久就会变慢.
R也只看到它创建的内存中的对象,而不是它所解释的对象,因此你的Java kulch会在R不知道的情况下徘徊.所以如果JVM创建它,如果Java在休眠之前没有这样做,R将不会清理它.如果内存被选择性地回收,你可能会有碎片化的内存空白,这会影响性能.
我个人的做法是创建组,变量,框架...子集只有我需要什么,然后rm()和gc()...删除并强制垃圾收集.
继续下一步并进行繁重的工作.如果我运行一个基于Java的包,我会更频繁地进行清除以保持内存清洁.
完成Java过程后,我会使用detach(yourlibraryname)并gc()清除所有内容.
如果你已经调整了'堆',我会在这里写下重新调整,从而降低你给Javas动态内存的分配,因为如果Java虚拟机仍在使用但是没有运行,R无法将其恢复已经能够确定.所以你应该重置它并回馈R什么是R使用.我认为从长远来看,它将使您受益更快,更少锁定.
在您使用它时,了解它如何影响您的系统的最佳方法是使用sys.time或proc.time函数来查看您的脚本在有和没有强制垃圾收集,删除,分离和堆重新分配的情况下需要多长时间.
你可以在这里牢固掌握如何做到这一点:
希望这有助于一些!