2012-07-09 1030 views

回答

1

不,jmap -histo不会触发FullGC。我正在定期打印Histogram,并且没有在GC日志中看到任何完整的GC。

我不知道它是如何在虚拟机中实现的,但不需要担心完整的GC。

5

有更多JDK经验的人应该验证这一点,但我相当确信它确实触发了完整的GC,至少在OpenJDK 1.7。开始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); 
    } 

Jmap.histo()三元运算符使得以heapHisto来电jdk/src/share/classes/sun/tools/attach/HotSpotVirtualMachine.java-live说法:

// Heap histogram (heap inspection in HotSpot) 
public InputStream heapHisto(Object ... args) throws IOException { 
    return executeCommand("inspectheap", args); 
} 

如果我们看一下inspectheap本身,在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; 
} 

注意,特别是live_objects_only strc mp和由此产生的heapop稍后调用两行。如果inspectheap通过任何途径获得参数-live,它将请求完整的gc。

0

以我的经验:是的,这is.when你做这个实验,你可以使用命令:

sudo -utomcat jstat -gcutil {PID} 1000 1000 

描述: 第一个参数经过1000 PID是打印时间间隔。 pid之后的第二个参数1000是循环计数。 使用此命令可以监视JVM GC activity.you可以看到完整的GC时间和计数象下面这样:

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

,现在你可以在其他终端执行JMAP命令,首先,你执行命令,但不带:live参数,然后使用此参数再次执行该命令时,当使用;live参数执行该命令时,应看到完整的gc活动,换言之,完整的gc计数将递增。

第二个命令可能是这样的:

sudo -u tomcat /home/path/to/jmap -histo:live {pid} | head -n 40

顺便说一句,我的JDK版本是JDK7

1

jmap -histo触发一个完整的GC,但jmap -histo:live意志。