我怎么知道谁调用System.gc()?

时间:2011-07-29 08:57:06

标签: java logging garbage-collection stack-trace

在正在运行的系统中,我们看到很多“Full GC(System)”,表示有人触发System.gc()。

有没有办法找出代码中的这个位置?

我确实搜索了所有可用的来源,但没有发现任何可疑因此它必须在某个地方,可能是在同一个容器或容器本身中运行的另一个应用程序。

4 个答案:

答案 0 :(得分:8)

您可以更改Runtime类以记录将gc()调用到文件的位置(System.gc()调用Runtime.gc())

要执行此操作,请编辑副本,对其进行编译并将其添加到-Xbootclasspath/p:

然而,大量的Full GC更有可能是由于幸存者空间不足或完整的终身空间造成的。

你能试试吗

jstat -gccause {pid} 5s 

答案 1 :(得分:3)

您使用的某些库可能会调用显式gc。您可以使用-XX:-DisableExplicitGC停用它,并查看它是否在日志中停止Full GC

答案 2 :(得分:2)

使用以下支撑脚本&使用 btrace插件 jvisualvm 会轻松显示System.gc的来电者。

// import all BTrace annotations
import com.sun.btrace.annotations.*;

// import statics from BTraceUtils class
import static com.sun.btrace.BTraceUtils.*;

// @BTrace annotation tells that this is a BTrace program
@BTrace
public class GCcaller {
    // @OnMethod annotation tells where to probe.
    // In this example, we are interested in entry
    // into the Thread.start() method.
    @OnMethod(
        clazz="java.lang.System",
        method="gc"
    )
    public static void func() {
        // println is defined in BTraceUtils
        // you can only call the static methods of BTraceUtils
        println("about to start a System.gc!");
        jstack();
    }
}

答案 3 :(得分:1)

在Java中,您无法“调用”垃圾收集器。如果在调用System.gc()方法时看到documentation,则vm仅作为运行垃圾收集器的建议,但无法保证有效调用。即使您在堆栈中需要空间时不调用,也会自动调用内部进程。

如果您看到很多Full GC,则可能是应用程序未正确释放资源的症状。您应该监视堆以查看问题是什么