线上机器CPU负载过高如何去排查?如何优化JVM参数?

 

(1)第一可以通过 top -Hp PID , jstack PID等查看占用CPU资源过高的线程是哪些?可能会看到是GC线程。
或者是其他线程,如果是GC线程,那么jstat查看JVM垃圾回收器工作的情况。如果是其他业务线程,可能需要跟踪栈信息,追踪到代码中进行分析。(可能是一直循环处理业务,数据量大,处理耗时。)
-- 业务线程导致CPU高的场景,没有关注过,不知道我的理解对不对。
(2)查看JVM垃圾回收情况相关的信息
YoungGC频率,YoungGC耗时,每次GC过后Eden+S0区的垃圾回收情况;进入老年代的大小
FullGC频率,YoungGC耗时,每次GC过后老年代的垃圾回收情况;
我的总结:
(1)如果是YoungGC,FullGC频繁,但是每次FullGC回收之后,垃圾回收率很高,可能就是高并发引起的;要关注下是不是年轻代内存分配不合理,是否需要加大JVM堆内存。升级机器等。根据YoungGC每次进入老年代的大小,重新预估一下,新生代需要分配多大的内存比较合适,来解决这个高并发引起的FullGC问题。
(2)如果FullGC之后,回收的内存时多时少,或者说很少,甚至可能出现连续的1-3次,回收之后,老年代剩余空间是在增长的,这个时候就要排除是否有发生内存泄漏的嫌疑。或者说高并发引起的问题导致对象无法被回收。这时候一般需要dump下内存快照,使用MAT工具分析内存快照,可以短时间连续dump两次,对比两次内存快照,查看哪些对象不断在增长。这些对象是不是大对象,因为并发问题无法被及时回收,JVM处在OOM边缘。然后根据派排查结果,优化代码问题。
优化JVM参数:
(1)优化新生代和老年代的占比。尽量保证每次YoungGC之后。可以打印对内存信息,计算一下一般存活对象是多大。假设是100M。那么可以将S0设置成 S0 * 50% = 100M。 S0大概需要200M。这样就可以把Eden和老年代大小预估出来了,一般业务系统。老年代分配1至2G就可以了。
(2)需要开启CMS垃圾回收器的对内存碎片进行整理。一般每次FullGC都整理一遍最好。
(3)-XX:CMSInitiatingOccupancyFraction=92。老年代占用92%以上发生FullGC。一般这个值我觉得偏大了,如果是高并发系统,会有较大可能出现Concurrent Mode Failure。所以我对CMS设置的时候,会把老年代预留空间大小预估到S0区大小这样。一般设置80%。对于这点不知道是否合理?
(4)还会设置一些额外的参数:-XX:-OmitStackTraceInFastThrow
还有打印GC日志,发生OOM的时候dump内存快照参数。
(5)还有一点,如果没有发生什么特殊的问题,不会对其他的参数进行优化。能简单设置就采用简单的设置。

 

转载,如有侵权,请联系删除。

posted @ 2021-03-05 11:20  四块五  阅读(531)  评论(0编辑  收藏  举报