近日开始关注JVM的问题,先用jstat -gcutil pid随意看了一套web系统的JVM情况(容器是tomcat 7,jdk是1.7),结果非常惊讶,Full GC频繁,且周期性出现。

 

    问题出现了,好兴奋啊,搞定它我就能增长经验了哇!!于是乎,和我们亲爱的SA同事交流了一番,我用nohup jstat -gccause pid 1s >> ~/xxx/xxx.log &先把gccause日志记录下来,经过半天日志记录追踪之后,发现LGCC是System.gc()。很好奇怎么会出现这东西,我写的代码肯定没有System.gc(),有点怀疑是tomcat的问题(当时也只是怀疑,无任何根据的)。为了解决这个问题,我先尝试在JVM启动参数中加入-XX:+DisableExplicitGC来禁止System.gc(),大半天后再用jstat看gc情况,FGC的次数是0,然后问题解决了。

 

    虽然问题临时解决了,为了知其然知其所以然,我继续深究了一番,最终找到了问题所在:是tomcat 7的一个默认配置(JreMemoryLeakPreventionListener)所导致的,更合适的解决方法似乎是 <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" gcDaemonProtection="false"/>。

 

    以下是引用的内容,原文网址在:http://mail-archives.apache.org/mod_mbox/tomcat-users/201008.mbox/%3CAANLkTino=BjP5LsBCwncB2HvNDzyKLr5y-8yWdt15a89@mail.gmail.com%3E

 

Html代码   收藏代码
  1. Thank you Konstantin and Chris for your attention.  
  2.   
  3. As stated in the initial post:  
  4. 'We have recently deployed tomcat-6.0.28 in our organization and are  
  5. noticing every hour, a Full GC is occurring.  The same application,  
  6. same JVM, same JVM args, just a new tomcat release.'  
  7.   
  8. Using the default JreMemoryLeakPreventionListener configuration that  
  9. has 'gcDaemonProtection=true'  will result in 1hr FullGCs using Sun  
  10. 1.6 b18, b20 and b21on Solaris and Windows. We've tested and  
  11. successfully 'contained' the FullGC behavior using one of the below  
  12. configurations:  
  13.   
  14. 1) suppress the FullGC using JVM arg -XX:+DisableExplicitGC  
  15.   
  16. 2) keep the FullGC but to defer to the CMS collector using JVM arg  
  17. -XX:+ExplicitGCInvokesConcurrent  
  18.   
  19. 3) <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"  
  20. gcDaemonProtection="false"/>  
  21.   
  22. 4) Disable the listener altogether  
  23.   
  24.   
  25. We've decided to go with option 3.  
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐