Java中的热切垃圾收集

Jon*_*han 3 java garbage-collection jvm

我想更好地了解我的应用程序,特别是它的内存占用.

我确实理解垃圾收集的概念,我知道堆中总会有一定数量的死对象,但是,我想最小化这个数量,以便用JConsole(或JVisualVM)进行监视为我提供了有关当前所需(未占用)空间的一些信息.

有没有办法在SunVM中配置现有的垃圾收集器(例如G1GC),以便(以响应性和运行时为代价)最小化堆中死对象的数量?

澄清

为了更清楚我的目标:我的应用程序是非交互式的,因此两次运行之间随着时间的推移,内存占用量大致相同.我想确定所需的最小堆空间以及代码更改对该占用空间的影响.由于死对象,JConsole的输出在这里并没有真正帮助.我也想知道,我的峰值记忆是否确实在某个时间点是一个突出的峰值,或者它是否随着时间的推移而拉伸.这就是为什么在我到达OOME之前减少Xmx并不是什么让我在那里.

另外:我说的是在开发人员测试期间使用,而不是在生产中使用.在生产中,通过性能和性能 - 当然 - 比更现实的memroy足迹更重要.

sse*_*ano 5

如果您想知道应用程序使用的内存总量,您必须在相当长的时间内监视它.应用程序随机时刻的堆样本:

jps -> output the pid of java process
jmap -dump:live,format=b,file=heap.bin [pid]
Run Code Online (Sandbox Code Playgroud)

然后jhat导航堆.还有其他工具可以做到这一点.

这样做,你会立刻知道堆上的内容.

请记住,诸如memory mapped files未存储在堆中但存储在内存中的对象.

到达时OOM尝试添加此项,然后读取输出以查看哪些对象实际位于堆中:

-XX:-HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./java_pid<pid>.hprof
Run Code Online (Sandbox Code Playgroud)

为此,请启用GC log,然后使用GCViewer等工具.

-XX:+PrintGCTimeStamps
 -XX:+PrintGCDetails
-verbose:gc
-Xloggc:garbage_collector -> this set the file of the output
Run Code Online (Sandbox Code Playgroud)

当你谈论堆时,我知道你在谈论tenured空间.如果是这样,您需要知道对象的平均寿命.并遵循一些最佳实践,然后进行精细调整.还要记住,发布一个System.gc()并不能保证GC执行该操作.

事情就是实例进行young generation (eden),当它满了时minor GC执行.仍可访问的对象将传递给调用的两个空间之一survivor.一旦这个空间被填满tenured.完成后,full GC执行并删除所有无法访问的实例.

你可以做的一件事是primitives在方法中使用.那些不会放在堆中,因为它们的生命跨度在线程堆栈中.

有用的参数是那些与大小相关的参数ternured and young generation (eden).这些按比例工作.如果你要发出许多请GC记住设置最长时间GC stop.

一些有趣的参数是:

-XX:MinFreeHeapRatio=  
-XX:MaxHeapFreeRatio=  
-XX:NewRatio=
-XX:SurvivorRatio
Run Code Online (Sandbox Code Playgroud)

例如,设置-XX:NewRatio=3意味着年轻一代和老一代之间的比例是1:3; 换句话说,伊甸园和幸存者空间的总和将是堆的四分之一.

无论如何,我不知道为什么你需要这个要求.我通常只担心throughputthroughput坏的时候只关心那些参数.