又一个勉强算是解决的Case

最近真心陷入了怪圈,近期处理的cases要么是没解决,要么就是稀里糊涂的解决掉,这周又碰到了一个这样的case,尽管目前是解决了,但其实背后的原因仍然不清楚,给大家分享下先,是一个关于Young GC越来越慢的Case。

应用的现象是启动的那段时间每次Young GC耗时大概是10-20ms,运行几个小时后,Young GC的耗时就会逐步增长到200+ms(注意,是逐步增长,不是突然增长到这么大),继续运行的话,甚至会逐步增长到1s以上,但每次Young GC存活的对象和刚启动的那段时间其实没什么变化。

之前也碰到过几次Young GC变慢的现象,原因是:
1. CMS GC的碎片问题;
2. 用到了Swap。

于是按照这两个思路去排查,看应用的启动参数,应用确实是采用的CMS GC,于是我就强制触发了下Full GC,结果发现还是一样,没什么变化,说明不是碎片问题造成的。

接着查是不是用到了Swap,free -m可以看到swap也没用过,这个时候我只好怀疑是不是内存条出什么问题了,请硬件的同事帮忙check了下内存条是ok的。

到了这步,又悲催了,超出了自己的经验范围,于是想着要么换一个GC方式试试,就把CMS GC换成了ParallelOldGC,结果还是一样。

到这个阶段已经彻底没哲了,开始瞎折腾,就在瞎折腾的那段时间突然发现了一个现象,就是permgen涨的很快,当然,fgc的时候也会回收掉,于是就想着先用btrace挂上看看为什么permgen涨的快。

可是这个应用是用的jdk 7,挂上btrace跟踪后直接crash了…只好按照这个思路去问应用的同学,按以往经验,permgen涨的快通常都是因为错误使用groovy,于是直接问是不是用到了groovy,答复是用到了,不过用的方法是jdk 7 invokedynamic的方式去执行的groovy脚本,而在这种情况下执行的方式其实是把groovy脚本编译成class来执行的,所以理论上不太可能出现重复装载class,但btrace脚本又挂不上,就很难去排查了。

这个时候应用的同学告诉了一个有用的信息是,这个应用最近从groovy 2.1.x升级到了2.3.x,猜想莫非是升级造成的,于是降级成2.1.9,再看,一切恢复正常了,到此问题算是解决了。

这个问题是解决了,但其实遗留了好几个疑问点还不知道原因:
1. 为什么permgen一直增长/回收,会造成ygc变得越来越慢,完全无法理解呀;
2. Groovy 2.3.x到底做了什么导致了class的不断重复装载,猜想是API上做了变化,还没来得及仔细看。

有经验的同学可以帮忙告知下我,谢谢,:)

=============================
欢迎关注微信公众号:hellojavacases

关于此微信号:
分享Java问题排查的Case、Java业界的动态和新技术、Java的一些小知识点Test,以及和大家一起讨论一些Java问题或场景,这里只有Java细节的分享,没有大道理、大架构和大框架。

公众号上发布的消息都存放在http://hellojava.info上。