一次Tomcat6.0.33版本与6.0.44版本差异所引发的问题

来源:互联网 发布:内衣淘宝店铺名字大全 编辑:程序博客网 时间:2024/04/29 18:15

前序(公司应用为Web应用, 部署服务器Linux + Nginx + Tomcat )

一天收到公司报警邮件,显示个别机器方法调用严重超时,平常都是在100ms以内响应的方法,突然某段时间响应时间上升到几秒,开始怀疑是机器的问题,临时把机器从线上摘掉,重启完之后再挂到线上,通过一段时间观察发现各方法响应时间正常。

又过了几天,发现好几台机器都出现这样的情况,感觉不是机器的问题,开始对jvm进行分析,通过分析发现,系统young gc耗时从开始的10ms左右慢慢上升到几百毫秒,old区使用超过了90%,而且系统没有进行过full gc,再看其他方法响应时间正常的机器,young gc一般10ms左右,但是每隔一小时执行一次full gc,full gc耗时几百毫秒,而old区几乎每隔四小时就会清空,感觉机器响应慢的问题与young gc耗时长有很大关系,通过上网查找资料,发现young gc耗时与old区使用大小有很大关系,如果old区使用太大,执行young gc就会很耗时,导致系统响应时间变慢。

虽然找到了系统响应时间变慢的原因,但是不知道具体是什么原因导致的,因为机器都是相同的,而且也没有显示调用System.gc()的代码,后来通过对比异常机器与正常机器的各项配置,发现正常的机器Tomcat版本号为6.0.33,异常机器Tomcat版本号都为6.0.44,咋一看感觉Tomcat版本都一样,没有差别,不过还是不放心,就找到这两个Tomcat版本的源码,查找是否有显式调用System.gc()的方法,通过查找发现,Tomcat版本6.0.33 的内存泄露监听器JreMemoryLeakPreventionListener,每隔一小时就会调用一次System.gc(),而Tomcat版本6.0.44的内存泄露监听器调用一次System.gc()的时间间隔为Integer.max -1 s,几乎不会显式的调用System.gc()。

以上终于找到了问题所在,Tomcat版本改为了6.0.33,之后系统恢复正常。

2 0