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

34

我今天在尝试使用 jmap -histojmap -dump

当按照此顺序运行时:

jmap -dump:format=b,file=heap.1 [pid]
jmap -dump:live,format=b,file=heap.2 [pid]
jmap -dump:format=b,file=heap.3 [pid]

heap.3相对于heap.1更像heap.2。特别是,我在heap.1中感兴趣的“死”对象在heap.3中不存在。

看到这个情况,我开始寻找能告诉我应该期望什么的文档。我找到的最接近的是这个讨论,briand和alanb的评论表明,在实践中使用live选项时可以期望发生此GC;但是这些答案已经五年了,而且在论坛上发布似乎有点不正式,不太适用于规范。

我在哪里可以找到当前行为的文档记录?

1个回答

42
为了确定存活性,Java必须运行完整的GC,所以是的,它会这样做。

为了解决问题...这里是答案,如果有人需要深入了解,请随意。

/hotspot/agent/src/share/vm/services/attachListener.cpp 的一部分 取自

openjdk http://download.java.net/openjdk/jdk7/ 并且你必须接受 http://www.gnu.org/licenses/gpl-2.0.html

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

在vmGCOperations.hpp中,这是定义。
`VM_GC_HeapInspection(outputStream* out, bool request_full_gc,
                   bool need_prologue) :`

我可以查看源代码本身,但Java确定活性的唯一方法是运行完整的GC。 - bestsss
Java进行年轻代GC的方式是“简单”的:我们有一个记忆集,其中包含所有指向年轻代GC的旧对象的指针(并且有一些机制来捕获旧对象的更改)。这意味着,如果您仅运行年轻代GC,则假定记忆集中的每个对象仍然存活。因此,即使唯一指向年轻对象的指针来自已死的旧对象,您也不会销毁年轻对象。仅出于这个原因,即使您只对年轻堆的存活性感兴趣,也需要进行完整的GC。 - Voo
1
类似于-histo选项,live子选项是可选的,并指定只转储活动对象。同意,这并没有直接告诉我们GC运行的情况,但正如之前提到的那样,这可能是唯一(也是最方便)的方法。 - David Lantos
@HannoFietz,好的,我会给您提供源代码。 - bestsss
真的只是一个小修正——接受GPL并不是必须的。“你没有签署这个许可证,因此你不需要接受它。”但是如果你不接受它,你仍然受版权法的约束。 - GargantuChet
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接