JVM性能问题
JVM性能问题,大体上可以分为以下2大类:
内存问题
- 不合适的GC引起的停顿(Stop The World)
- 内存耗尽(Out Of Memory)
线程问题
- 死锁(Dead Lock)
- Looping Thread
- 锁竞争(High Lock Contention)
1、GC引起的停顿
GC停顿是JVM垃圾回收过程中的一个正常环节,对于正常的运行过程而言并不是问题,除非发生以下两种情况:
- 时间过长
- 频率过高
问题现象
- 周期性CPU飙高
- 周期性响应时间变长
问题定位
- 启动JVM时使用-verbosegc参数,然后在日志文件中搜索“FULL GC”
- 使用监控工具,当CPU占用过高时报警
如何避免?
- 合理配置heap,避免生命周期较短的对象进入老年代。新生代大小设置为比heap的一半略小,这种配置可以使得大部分短生命周期的对象在新生代直接回收
- -XX:MaxNewSize
- -XX:NewSize
- -XX:SurvivorRatio=6(表示Survivor:Eden=1:6,即Survivor占新生代的1/8)
- 开启CMS垃圾回收器,尽管这种方式会在一定程度上提高CPU占用率
- 针对容器环境运行的JVM,可以采取定期重启的方式,在Major GC到来之前,重启JVM
2、内存耗尽
OOM通常是由于内存泄漏引起,JVM内部的GC避免了忘记手动回收的问题,但是仍然无法避免开发人员的失误。 长时间持有不再需要的对象,会使得JVM无法正确执行GC。
问题现象
OOM引起的问题比较严重,必须通过重启解决。
问题定位
根据经验,内存泄漏通常是容器持有大量对象引起的,排查问题的时候可以优先关注容器当中是否存在不需要使用的对象。一个例子是session相关的容器。
- -XX:HeapDumpOnOutOfMemoryError