JVM性能分析

474 阅读2分钟

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占用过高时报警

如何避免?

  1. 合理配置heap,避免生命周期较短的对象进入老年代。新生代大小设置为比heap的一半略小,这种配置可以使得大部分短生命周期的对象在新生代直接回收
  • -XX:MaxNewSize
  • -XX:NewSize
  • -XX:SurvivorRatio=6(表示Survivor:Eden=1:6,即Survivor占新生代的1/8)
  1. 开启CMS垃圾回收器,尽管这种方式会在一定程度上提高CPU占用率
  2. 针对容器环境运行的JVM,可以采取定期重启的方式,在Major GC到来之前,重启JVM

2、内存耗尽

OOM通常是由于内存泄漏引起,JVM内部的GC避免了忘记手动回收的问题,但是仍然无法避免开发人员的失误。 长时间持有不再需要的对象,会使得JVM无法正确执行GC。

问题现象

OOM引起的问题比较严重,必须通过重启解决。

问题定位

根据经验,内存泄漏通常是容器持有大量对象引起的,排查问题的时候可以优先关注容器当中是否存在不需要使用的对象。一个例子是session相关的容器。

  • -XX:HeapDumpOnOutOfMemoryError