2

我观察到每 60 分钟将“Full GC (System)”消息写入我的日志。当我这样做时:

jstat -gccause {pid} 5s 

我看到这是来自对 System.gc() 的显式调用。我正在尝试追踪调用 System.gc() 的代码,因为我怀疑这发生在我的一个依赖项中,而不是我自己的代码中。

我确实意识到我可以使用 -XX:-DisableExplicitGC 禁用显式 GC 调用,但我需要弄清楚调用的来源。我在这里这里读到这个人能够在调用 gc() 时更改运行时类以记录堆栈跟踪。但我不清楚如何做到这一点。有人可以指出我正确的方向吗?

4

3 回答 3

2

获取 Runtime.java 的源代码,并在 gc() 方法中添加代码:

try {
    throw new Exception("Who is the GC culprit?");
} catch (Exception e) {
    e.printStackTrace();
}

编译类后,用新的类文件更新 rt.jar。

于 2013-04-11T20:15:55.930 回答
0

您的应用程序是否通过 RMI 被其他应用程序访问/访问?使用远程方法调用,您将遇到 RMI 的分布式垃圾收集 (DGC),它基本上是这样的:RMI 定期调用 System.gc()。

${sun.rmi.dgc.client.gcInterval}对于客户端,每毫秒触发一次 Full GC 。${sun.rmi.dgc.server.gcInterval}对于服务器,每毫秒触发一次 Full GC 。

这些时间间隔的默认值因 JDK 的版本而异。它曾经是每分钟一次(是的......),但已更改为每 30 分钟一次。如果您设置了这些环境变量,您可能会有不同的值,例如,如果您设置了-Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000.

来源:http ://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#other_considerations

于 2013-04-14T17:36:53.070 回答
0

也许获取调用 gc() 的代码的最简单方法是将您的应用程序代码放入 IDE(eclipse 或 idea..)下载所有源代码(如果使用 maven 管理您的 lib,它可能很简单)并找到 System.gc 的参考() 或 Runtime.getRuntime.gc()。

于 2013-04-12T06:59:33.910 回答