距离上一次大bug过去了两三个月, 稳定了一段时间后, 最近出现的bug情况是:
堆使用正常, 线程正常, tomcat 日志也正常没报错。 但是cpu使用率频繁百分之百, 频繁gc.导致用户反应程序使用时会卡顿。 。
现象为:
jvm 参数设置为: 最大堆 -Xmx4096m,初始化 -Xms4096m, 新生代 -Xmn2048m, GC回收器是 CMS.
新生代内存是 一个 eden + survivor, 默认比例是 8:1, eden区内存大小为: 1658112kb, survivor区内存大小为:207232kb.
内存分配及使用这一块是没什么问题, 然后加上 -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:/soft/gclog/gc.log
打印gc的日志分析后,找到了原因:
同事在代码的catch中 加入了 system.gc 方法。 这个接口是第三方接口,调用有时候会报错。 所以导致 发生 full gc,
而 full gc 是会触发 stw (stop-the- word) ,也就是 在full gc时 会让应用程序停顿。 所以会导致 cpu 百分之百, 频繁gc.
解决方法就是: 将代码中的System.gc 注释, 然后将备机的 tomcat的war包下载, 替换 class后上传到tomcat. 在备机重启后。在dubbo-admin中将这个接口服务的主机服务禁用, 主备机接口调用全都 调用备机的。
gc日志:
新生区的 eden区:
新生区的 survivor区:
在备机重启后的状态就恢复正常: