我应该在使用后重置Java堆空间吗?

时间:2016-04-20 15:40:57

标签: java r memory-management heap-memory

我正在使用R中的一些建模算法,其中一个在Java(bartMachine)中运行。我发现,在运行建模算法之前,我需要根据数据的大小增加java的最大堆空间。

我这样做是这样的:

options(java.parameters = "-Xmx16g")

我的问题是,如果没有其他算法将使用java(或至少那么多堆空间),我是否需要重置堆空间?或者是否会根据需要回收分配给java的内存而不会造成性能损失?

我已经搜索了一些关于这个主题的内容,并且我理解如何来更改/降低堆空间。我也明白R / Java会做垃圾收集来从内存中删除旧对象以释放更多空间。

我不明白的是,更改堆空间会如何影响其他程序可用的内存,以及在这种情况下是否有必要或甚至是一个好主意来改变使用后的堆大小。

我已经看过的一些答案/资源:

Is there a way to lower Java heap when not in use?

Java garbage collector - When does it collect?

http://www.bramschoenmakers.nl/en/node/726

https://cran.r-project.org/web/packages/bartMachine/bartMachine.pdf

2 个答案:

答案 0 :(得分:5)

它的实现定义并取决于由很多参数影响的实现。 The garbage collector can affect it。在使用Oracles JVM 1.7的Mac上,它默认为并行收集器-XX:+UseParallelGC,并且此收集器不会将内存释放回操作系统。我在Mac上尝试了它,除了使用-XX:+UseG1GC之外,它没有释放任何东西。您可以使用此功能查看默认版本:

java -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -version

如果您使用支持它的JVM和正确的垃圾收集器,可以使用一些参数来调整内存的释放,即

-XX:MinHeapFreeRatio (default is 40)
-XX:MaxHeapFreeRatio (default is 70)

但它们会被击中和错过(JVM决定何时释放内存,只释放大量对象可能不会触发它)。

答案 1 :(得分:5)

我最近使用了非常重的Java程序,感受到了你的痛苦。

我不能告诉你是否根据一个不可否认的技术事实重置动态分配的内存,但我的个人经验告诉我,如果你要在Java工作后继续在本机R环境中处理,你可能应该。最好控制你的能力。

原因如下:

我唯一一次内存耗尽(甚至使用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.timeproc.time函数来查看您的脚本在有和没有强制垃圾收集,删除的情况下需要多长时间,分离和堆重新分配。

你可以在这里牢固掌握如何做到这一点:

IDRE -UCLE proc.time functions

希望这会有所帮助!