3

我们知道 jmap -histo:live 会触发完整的 gc 以确定活动对象:

使用 live 选项时,jmap 是否强制进行垃圾收集?

由于 jmap -histo 考虑了堆中的所有对象(年轻代和老年代的对象),我的观点是, jmap -histo 也可以触发完整的 gc。但是,我找不到关于 jmap -histo 是否会触发完整 gc 的可靠文档。

jmap -histo 可以触发完整的垃圾收集吗?

4

4 回答 4

8

jmap -histo 不会触发完整的 gc,但jmap -histo:live

于 2017-02-24T02:58:30.607 回答
6

有更多 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);
    }

三元运算符 in使用参数Jmap.histo()调用 heapHisto in :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_onlystrcmp 和结果在heapop两行之后调用。如果通过任何途径inspectheap获取-live参数,它会请求完整的 gc。

于 2013-04-01T17:06:55.977 回答
1

不,jmap -histo不会触发 FullGC。我经常打印直方图,在我的 GC 日志中看不到任何 Full GC。

我不知道它是如何在 VM 中实现的,但您不必担心完整的 GC。

于 2013-01-05T06:09:24.707 回答
0

以我的经验:是的,它是。当你做这个实验时,你可以使用命令:

 sudo -utomcat jstat -gcutil {PID} 1000 1000

说明:pid后面的第一个参数1000是打印的时间间隔。pid 之后的第二个参数 1000 是循环计数。使用这个命令你可以监控 jvm gc 活动。你可以看到完整的 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

于 2017-01-22T05:26:26.353 回答