8

When I run jcmd PID help GC.heap_dump, the help clearly says that full GC will be called, unless -all flag is specified:

GC.heap_dump ... Impact: High: Depends on Java heap size and content. Request a full GC unless the '-all' option is specified. <...>

-all : [optional] Inspect all objects, including unreachable objects (BOOLEAN, false)

If I run jcmd PID help GC.class_histogram, the help doesn't say anything about forcing a full GC, however "Impact" is still said to be "high", and the option still has an -all flag, which behaves exactly as for GC.heap_dump:

GC.class_histogram ... Impact: High: Depends on Java heap size and content.

-all : [optional] Inspect all objects, including unreachable objects (BOOLEAN, false)

I tried to run this command on couple of environments, and full GC was not called. However, since it "Depends on Java heap size and content" I cannot be sure.

So can jcmd PID GC.class_histogram call a full GC in some circumstances? If yes, what are they?

timbre timbre
  • 12,648
  • 10
  • 46
  • 77

2 Answers2

13

jcmd PID GC.class_histogram will cause Full GC by default.

If the target JVM is launched with -XX:+PrintGC, you will see a log message like

// 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

However, with -all option there will be no Full GC for GC.class_histogram, exactly like for GC.heap_dump. Find the proof in HotSpot sources:

void ClassHistogramDCmd::execute(DCmdSource source, TRAPS) {
  VM_GC_HeapInspection heapop(output(),
                              !_all.value() /* request full gc if false */);
  VMThread::execute(&heapop);
}
apangin
  • 92,924
  • 10
  • 193
  • 247
1

You could try to run jcmd PID GC.run before 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

But I'm not sure that there is any guarantee that JVM will actually perform GC upon that request. Javadoc for System.gc() says this:

 When control returns from the method call, the Java Virtual
 Machine has made a best effort to reclaim space from all discarded objects
Ivan
  • 8,508
  • 2
  • 19
  • 30
  • 1
    Thank. But it's not that I want full GC to run before that command, I just want to know reliably if the class histogram it gives me was before or after GC. – timbre timbre Jan 25 '18 at 17:07
  • @KirilS. I think that jcmd command will not attempt to call GC, but there is no guarantee that JVM which runs your application doesn't decide to run GC because it needs some memory just before you call jcmd. To cehck that you could start your application with `-verbose:gc` and monitor GC activity while calling jcmd – Ivan Jan 25 '18 at 17:34
  • I would think so too, but look at the second answer: apparently it does full GC every time. Not sure why I didn't see it on my test.. but there it is. – timbre timbre Jan 25 '18 at 17:48