如果您想知道您的应用程序正在使用的内存总量,您必须监视它相当长的时间。应用程序随机时刻的堆样本:
jps -> output the pid of java process
jmap -dump:live,format=b,file=heap.bin [pid]
然后jhat导航堆。还有其他工具可以做到这一点。
这样做你会立刻知道堆上有什么。
请记住,诸如此类的对象memory mapped files不存储在堆中,而是存储在内存中。
到达时OOM尝试添加它,然后读取输出以查看哪些对象实际上在堆中:
-XX:-HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./java_pid<pid>.hprof
为此,请启用GC log并使用诸如GCViewer 之类的工具。
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-verbose:gc
-Xloggc:garbage_collector -> this set the file of the output
当您谈论堆时,我知道您在谈论tenured空间。如果是这样,您需要知道对象的平均寿命。并遵循一些最佳实践,然后进行微调。还要记住,发出 aSystem.gc()并不能保证GC执行了。
事情是实例去young generation (eden)并且当它充满时minor GC执行。仍然可以访问的对象被传递到称为 的两个空间之一survivor。一旦这个空间被填满,空间就会被转储到tenured. 当已满时,afull GC会执行并删除所有无法访问的实例。
您可以做的一件事是primitives在方法中使用。那些不会放在堆中,因为它们的生命周期在线程堆栈中。
有用的参数是那些与tenured and young generation (eden). 这些按比例起作用。如果您要发出许多问题,请GC记住为GC stop.
一些有趣的参数是:
-XX:MinFreeHeapRatio=
-XX:MaxHeapFreeRatio=
-XX:NewRatio=
-XX:SurvivorRatio
例如,设置-XX:NewRatio=3表示年轻代和老年代的比例为1:3;换句话说,伊甸园和幸存者空间的组合大小将是堆的四分之一。
无论如何,我不知道你为什么需要这个要求。我通常只担心并且只在不好throughput时才关心这些参数。throughput