天天看点

jvm 优化 关闭一小时一次fullgc

tomcat版本是6.0.35。

1

tomcat的server.xml配置了

<!-- Prevent memory leaks due to use of particular java/javax APIs-->

 <ListenerclassName="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>

JreMemoryLeakPreventionListener这个类顾名思义是防止内存泄露的。

6.0.35的 org.apache.catalina.core.JreMemoryLeakPreventionListener的 261行有如下代码

if (gcDaemonProtection) {

                   try {

Class<?> clazz = Class.forName("sun.misc.GC");

                       Method method = clazz.getDeclaredMethod(

                               "requestLatency",

                               new Class[] {long.class});

                       method.invoke(null, Long.valueOf(3600000));

表明一小时显示的调用一次调用System.gc()。(按照sun jdk规范,不保证立即执行,并且注意的是,我们有时候监控到的fullGC不一定是这个触发的。)

我又看了6.0.43(6的最新版本)

Class<?> clazz = Class.forName("sun.misc.GC");

                       Method method = clazz.getDeclaredMethod(

                               "requestLatency",

                               new Class[] {long.class});

                       method.invoke(null, Long.valueOf(Long.MAX_VALUE - 1));

这个世界触发值,已经改为LONG的最大值,说明tomcat的高版本不再是一个小时显示的调用System.gc()了.

2

   a.可以注释掉这个   <ListenerclassName="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>

   b.看代码逻辑,可以加个gcDaemonProtection开关,<ListenerclassName="org.apache.catalina.core.JreMemoryLeakPreventionListener"gcDaemonProtection="false"/>

   c 通过 -XX:+DisableExplicitGC 来变相消除显式调用 full GC。

   d 可以升级tomcat。

    tomcat6.0.43以后fix了这个问题。

    tomcat7高版本【 现在线上镜像tomcat7.0.61】也不会有这个问题。

     二:cxf-common-utilities-2.5.2-sources.jar的org.apache.cxf.common.logging.JDKBugHacks

              代码和上面差不多,

              默认也会触发一小时fullgc一次.

对于性能要求高的高并发的系统,一小时一次fullgc,会周期性影响性能。

1建议升级tomcat到7以上

 2  如果一定要用cxf的话,升级cxf到2.8.0,并且在jvm启动参数添加,-Dorg.apache.cxf.JDKBugHacks.gcRequestLatency=true