如果您想知道您的应用程序正在使用的内存总量,您必须监视它相当长的时间。应用程序随机时刻的堆样本:
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