在正在运行的系统中,我们看到很多“Full GC(System)”,表示有人触发System.gc()。
有没有办法找出代码中的这个位置?
我确实搜索了所有可用的来源,但没有发现任何可疑因此它必须在某个地方,可能是在同一个容器或容器本身中运行的另一个应用程序。
答案 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,则可能是应用程序未正确释放资源的症状。您应该监视堆以查看问题是什么