【问题标题】:Heap dump with jmap throws NullPointerException使用 jmap 进行堆转储会引发 NullPointerException
【发布时间】:2015-02-18 14:17:49
【问题描述】:

我正在尝试使用 jmap 进行堆转储,但我不断收到 NPE。 我正在使用 Oracle 的 Java7 jdk(详情如下)。

$sudo jmap -F -dump:format=b,file=heap.bin 21966

Attaching to process ID 21966, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.71-b01
Attaching to process ID 21966, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.71-b01
Dumping heap to /tmp/dumps/2015-02-18T13:24:36Z-heap.bin ...
Exception in thread "main" java.lang.reflect.InvocationTargetException
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at sun.tools.jmap.JMap.runTool(JMap.java:197)
  at sun.tools.jmap.JMap.main(JMap.java:128)
Caused by: java.lang.NullPointerException
  at sun.jvm.hotspot.utilities.HeapHprofBinWriter.writeSymbolID(HeapHprofBinWriter.java:905)
  at sun.jvm.hotspot.utilities.HeapHprofBinWriter.writeFieldDescriptors(HeapHprofBinWriter.java:743)
  at sun.jvm.hotspot.utilities.HeapHprofBinWriter.writeClassDumpRecord(HeapHprofBinWriter.java:511)
  at sun.jvm.hotspot.utilities.HeapHprofBinWriter.access$000(HeapHprofBinWriter.java:297)
  at sun.jvm.hotspot.utilities.HeapHprofBinWriter$1.visit(HeapHprofBinWriter.java:446)
  at sun.jvm.hotspot.memory.SystemDictionary$2.visit(SystemDictionary.java:179)
  at sun.jvm.hotspot.memory.Dictionary.classesDo(Dictionary.java:69)
  at sun.jvm.hotspot.memory.SystemDictionary.classesDo(SystemDictionary.java:190)
  at sun.jvm.hotspot.memory.SystemDictionary.allClassesDo(SystemDictionary.java:183)
  at sun.jvm.hotspot.utilities.HeapHprofBinWriter.writeClassDumpRecords(HeapHprofBinWriter.java:443)
  at sun.jvm.hotspot.utilities.HeapHprofBinWriter.write(HeapHprofBinWriter.java:413)
  at sun.jvm.hotspot.tools.HeapDumper.run(HeapDumper.java:56)
  at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
  at sun.jvm.hotspot.tools.HeapDumper.main(HeapDumper.java:77)


$java -version
java version "1.7.0_71"
Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)

有人见过这个吗?谷歌搜索带来了 OpenJDK 的问题 (https://bugs.openjdk.java.net/browse/JDK-8028623) 但我不确定Oracle JDK是否有同样的问题。

【问题讨论】:

  • 你必须使用 -F 来进行转储吗?我的经验是,如果可以避免使用 -F,Java 工具会更加健壮。
  • 你是对的。我不需要 -F 选项。

标签: java jvm jmap


【解决方案1】:

是的,您找到了指向完全相同问题的正确链接。
它已在 JDK 7u72 中修复。

顺便说一句,-F 选项使jmap 以完全不同的方式工作。

  • 没有-F 的jmap 使用Dynamic Attach mechanism 连接到目标JVM,然后要求JVM 从JVM 进程中自行生成转储;
  • with -F jmap 使用Serviceability Agent 挂起目标JVM 进程,然后远程读取其内存,在一个单独的进程中完成所有工作。虽然 SA 是一个很酷且功能强大的工具,但它并没有很好地保持 100% 兼容最新的 JVM 实现细节。因此,遇到 SA 问题并不少见。

【讨论】:

  • 我设法通过以下方式使其工作: 1. 删除 -F 选项。 2. 以拥有该进程的用户身份运行 jmap。 3. 摆弄创建文件的目录权限(例如 chmod o+w /tmp/dumps)。非常感谢!
  • 我唯一的问题是:当使用动态附加机制时,假设 jvm 正忙于做 GC 或被占用(我的 GC 阈值超出了),它是否仍然响应请求堆转储?在这种情况下,我是否必须使用“-F”选项?
  • @Rajiv 是的,Dynamic Attach 的缺点是如果 JVM 忙于长时间运行的 GC 或其他什么,它可能不会响应。 -F 正是针对这些情况。否则动态附加会更快、更可靠。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 2021-04-20
  • 1970-01-01
相关资源
最近更新 更多