一.问题描述
环境:JDK1.8、CentOS 6.9、容器undertow、Spring boot 1.5.8
最近线上运维,发现gclog里打印了很多Full GC的日志,通关gclog前面的时间可以看到间隔时间都是在10小时左右。
大概看了一下都是调用了System.gc()产生的Full GC,然后查看堆栈信息还远远没到Full GC的条件。
二.问题排查
以下源码均只写出相关部分,其他省略。
1.问题猜测
以前应用都是正常GC,想到最近一次上线代码中引入了apache的cxf包,版本为2.7.6。找到其中一段代码:
package org.apache.cxf.common.logging;
public class JDKBugHacks{
public static void doHacks(){
//省略前面代码...
Method = method;
Class policyClass;
try{
if(!skipHack("org.apache.cxf.JDKBugHacks.gcRequestLatency")){
policyClass = Class.forName("sum.misc.GC");
method = policyClass.getDeclaredMethod("currentLatencyTarget");
Long l = (Long)mehtod.invoke((Object)null);
if(l != null && l.longValue() == 0L){
method = policyClass.getDeclaredMethod("requestLatency",Long.TYPE);
method.invoke((Object)null,36000000L);
}
}
}catch(Throwable var16){
;
}
//省略后面代码...
}
}
这段代码在不同条件下利用反射调用了sun.misc.GC
中的currentLatencyTarget
方法或者requestLatency
方法。而且刚好可以看到在进行requestLatency
方法调用时,传入的第二个参数如果单位是毫秒的话,刚好是10小时。现在就是要看一下GC这个类中的方法。
GC类中相关的源码:
package sum.misc;