We know that jmap -histo:live triggers a full gc in order to determine live objects:
Does jmap force garbage collection when the live option is used?
Since jmap -histo considers all objects in the heap (those in the young and old generation), my point is, jmap -histo can also trigger a full gc, too. However, I could not encounter a solid documentation about whether jmap -histo may trigger a full gc or not.
Can jmap -histo trigger full garbage collection?
Someone with more JDK experience should verify this, but I'm fairly confident it does trigger full GC, at least in OpenJDK 1.7. Start with jdk/src/share/classes/sun/tools/jmap/JMap.java
:
public class JMap {
...
private static String LIVE_HISTO_OPTION = "-histo:live";
...
...
} else if (option.equals(LIVE_HISTO_OPTION)) {
histo(pid, true);
...
private static final String LIVE_OBJECTS_OPTION = "-live";
private static final String ALL_OBJECTS_OPTION = "-all";
private static void histo(String pid, boolean live) throws IOException {
VirtualMachine vm = attach(pid);
InputStream in = ((HotSpotVirtualMachine)vm).
heapHisto(live ? LIVE_OBJECTS_OPTION : ALL_OBJECTS_OPTION);
drain(vm, in);
}
The ternary operator in Jmap.histo()
makes a call to heapHisto in jdk/src/share/classes/sun/tools/attach/HotSpotVirtualMachine.java
with the -live
argument:
// Heap histogram (heap inspection in HotSpot)
public InputStream heapHisto(Object ... args) throws IOException {
return executeCommand("inspectheap", args);
}
And if we look at inspectheap
itself, in hotspot/src/share/vm/services/attachListener.cpp
:
// Implementation of "inspectheap" command
//
// Input arguments :-
// arg0: "-live" or "-all"
static jint heap_inspection(AttachOperation* op, outputStream* out) {
bool live_objects_only = true; // default is true to retain the behavior before this change is made
const char* arg0 = op->arg(0);
if (arg0 != NULL && (strlen(arg0) > 0)) {
if (strcmp(arg0, "-all") != 0 && strcmp(arg0, "-live") != 0) {
out->print_cr("Invalid argument to inspectheap operation: %s", arg0);
return JNI_ERR;
}
live_objects_only = strcmp(arg0, "-live") == 0;
}
VM_GC_HeapInspection heapop(out, live_objects_only /* request full gc */, true /* need_prologue */);
VMThread::execute(&heapop);
return JNI_OK;
}
Note, in particular, the live_objects_only
strcmp and the resulting heapop
call two lines later. If inspectheap
gets the -live
argument via any avenue, it requests a full gc.
jmap -histo
will not trigger a full gc, but jmap -histo:live
will.
No, jmap -histo
will not trigger a FullGC. I am printing Histogram quite regularly and do not see any Full GCs in my GC logs.
I do not know how it is implemented in the VM but you do not need to worry about full GCs.
In my experience:yes,it is.when you do this experiment,you can use the command:
sudo -utomcat jstat -gcutil {PID} 1000 1000
description:
The first parameter 1000 after pid is time interval for print.
second parameter 1000 after pid is loop count.
use this command you can monitor the jvm gc activity.you can see the full gc time and count like below:
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 18.45 13.12 84.23 47.64 206149 5781.308 83 115.479 5896.786
0.00 21.84 5.64 84.24 47.64 206151 5781.358 83 115.479 5896.837
0.00 32.27 1.66 84.24 47.64 206153 5781.409 83 115.479 5896.888
0.00 13.96 53.54 84.24 47.64 206155 5781.450 83 115.479 5896.929
0.00 21.56 91.77 84.24 47.64 206157 5781.496 83 115.479 5896.974
and now you can execute the jmap command in other terminal,firstly,you execute the command without :live
parameter and then execute it again with this parameter ,you should see a full gc activity when the command is executed with ;live
parameter , in other word , the full gc count will increment.
The second command maybe like this:
sudo -u tomcat /home/path/to/jmap -histo:live {pid} | head -n 40
By the way,my JDK version is JDK7