对于还在正常运行的系统:
1.可以使用 jmap 来查看 JVM 中各个区域的使用情况
2.可以通过 jstack 来查看线程的运行情况,比如哪些线程阻塞、是否出现了死锁
3.可以通过 jstat 命令来查看垃圾回收的情况,特别是 full gc ,如果发现 full gct比较频繁,那么就得进行调优了
4.通过各个命令的结果,或者 jvisualvm 等工具来进行分析
5.首先,初步猜测频繁发送 full gc 的原因,如果频繁发生 full gc 但是又一直没有出现内存溢出,那么表示 full gc 实际上是回收了很多对象了,所以这些对象最好能在 younggc 过程中就直接回收掉,避免这些对象进入到老年代,对于这种情况,就要考虑这些存活时间不长的对象是不是比较大,导致年轻代放不下,直接进入到了老年代,尝试加大年轻代的大小,如果改完之后, full gc 减少,则证明修改有效
6.同时,还可以找到占用 CPU 最多的线程,定位到具体的方法,优化这个方法的执行,看是否能避免某些对象的创建,从而节省内存
对于已经发生了 OOM 的系统:
1.一般生产系统中都会设置当系统发生了 OOM 时,生成当时的 dump 文件(- XX :+ HeapDumpOnOutOfMemoryError - XX : HeapDumpPath =/ usr / local / base )
2.我们可以利用 jsisualvm 等工具来分析 dump 文件
3.根据 dump 文件找到异常的实例对象,和异常的线程(占用 CPU 高),定位到具体的代码4.然后再进行详细的分析和调试
总之,调优不是一蹴而就的,需要分析、推理、实践、总结、再分析,最终定位到具体的问题