在收集数据之前,`jcmd PID GC.class_histogram`会调用一个完整的GC吗?

时间:2018-01-25 15:45:05

标签: java performance garbage-collection jvm

当我运行jcmd PID help GC.heap_dump时,帮助明确表示将调用完整的GC,除非指定了-all标志:

  

GC.heap_dump   ...   影响:高:取决于Java堆大小和内容。除非指定了“-all”选项,否则请求完整的GC。 < ...>

     

-all:[可选]检查所有对象,包括无法访问的对象(BOOLEAN,false)

如果我运行jcmd PID help GC.class_histogram,该帮助没有说明强制使用完整的GC,但“影响”仍然被称为“高”,并且该选项仍然具有-all标志,其行为与GC.heap_dump完全相同:

  

GC.class_histogram   ...   影响:高:取决于Java堆大小和内容。

     

-all:[可选]检查所有对象,包括无法访问的对象(BOOLEAN,false)

我尝试在几个环境中运行此命令,并且未调用完整的GC。但是,由于“取决于Java堆大小和内容”,我无法确定。

在某些情况下,jcmd PID GC.class_histogram可以调用完整的GC吗?如果是的话,他们是什么?

2 个答案:

答案 0 :(得分:3)

jcmd PID GC.class_histogram默认会导致Full GC。

如果使用-XX:+PrintGC启动目标JVM,您将看到类似

的日志消息
// JDK 8:
[Full GC (Heap Inspection Initiated GC)  1397K->331K(126720K), 0.0023298 secs]

// JDK 9:
[15.503s][info   ][gc] GC(0) Pause Full (Heap Inspection Initiated GC) 2M->0M(8M) 8.107ms

但是,使用-all选项时,GC.class_histogram将没有完整的GC,与GC.heap_dump完全相同。在HotSpot sources中找到证据:

void ClassHistogramDCmd::execute(DCmdSource source, TRAPS) {
  VM_GC_HeapInspection heapop(output(),
                              !_all.value() /* request full gc if false */);
  VMThread::execute(&heapop);
}

答案 1 :(得分:1)

您可以尝试在jcmd PID GC.class_histogram

之前运行 jcmd PID help GC.run PID: GC.run Call java.lang.System.gc(). Impact: Medium: Depends on Java heap size and content. Syntax: GC.run
System.gc()

但我不确定是否有任何保证JVM会根据该请求实际执行GC。 When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects 的Javadoc说:

{{1}}