How can I tell who calls System.gc()?

2019-04-26 16:50发布

In a running system, we see lots of "Full GC (System)" which indicates someone triggers System.gc().

Is there a way to find out where in the code this happens?

I did search all the available source but found nothing suspicious so it must be somewhere, probably another app that's running in the same container or the container itself.

4条回答
祖国的老花朵
2楼-- · 2019-04-26 17:12

Some library which you use might call explicit gc. You can disable it with -XX:-DisableExplicitGC and take a look if it stops Full GC in the logs

查看更多
Luminary・发光体
3楼-- · 2019-04-26 17:12

Use following brace script & jvisualvm with btrace plugin will reveal the caller of System.gc easily.

// 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();
    }
}
查看更多
The star\"
4楼-- · 2019-04-26 17:20

In Java you cannot "call" the garbage collector. If you see the documentation when you call to the method System.gc(), the vm just takes as a suggestion to run the garbage collector, but there is no guarantee that is effectively called. Is an internal process that will be called automatically even if you don't call when it needs space in the stack.

If you are seeing a lot of Full GC, it may be a symptom of the application not releasing the resources correctly. You should monitor the heap to see what's the problem

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-04-26 17:22

You can change the Runtime class to log where gc() is being called to a file (System.gc() calls Runtime.gc())

To do this, edit a copy, compile it and add it to your -Xbootclasspath/p:

However a high number of Full GC is more likely to be due to insufficient survivor space or a full tenured space.

Can you try running

jstat -gccause {pid} 5s 
查看更多
登录 后发表回答