最近一个同事性能测试,20个并发,压了3分钟,tps急剧下降,jvm开始不响应 通过排查发现,此时old区已满,并且cpu 100%完全被vmthread占用 如果此时停止施压,那么过几分钟,jvm会回复。 也就是说垃圾回收停滞了。 通过MAT查看heap dump发现,有20多万的hibernate session 产生了超过1G的hashmap 无法回收 也就是在并发的情况,如果短时间产生大量的对象,会导致jvm vmthread出问题 于是采用缓存,减少直接的hibernate调用,症状消失 这使我又联想到之前的一个问题 同事的项目刚上线就出了问题,排查下来看到一个task(一个mq消费进程)一启动就cpu 100% 然后task完全不消费,进程停滞 于是通过jstack看到 vmthread 占用了 100% cpu 于是通过jstat 查看垃圾回收时发现heap占用100% 于是检查代码发现,由于多线程的原因,导致并发了加载了字典多次,导致heap 瞬间产生了 很多对象,导致vm thread工作不正常 修改程序确保只加载一次字典,症状消失 总体来说 cpu 100% 通常的思路是查看runnable的线程,但如果发现是耗尽cpu的是vmthread 多半会伴随old区已满(此时垃圾回收已停止),通常这是由于在并发下短时间内创建很多对象造成。 |
|