如何用我自己的实现替换Runtime.gc()?

时间:2013-04-11 20:09:00

标签: java garbage-collection jvm

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

jstat -gccause {pid} 5s 

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

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

3 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

对于客户端,每${sun.rmi.dgc.client.gcInterval} ms触发一次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