【问题标题】:Can't dump heap on java process无法在 Java 进程上转储堆
【发布时间】:2010-08-15 08:23:06
【问题描述】:

我有一个要调试的 java 进程。它的问题是它有太多打开的连接,所以运行 jmap 失败,因为它无法连接到进程。 运行 jmap -F 会产生下一个错误:

Attaching to process ID 1772, please wait...
sun.jvm.hotspot.debugger.NoSuchSymbolException: Could not find symbol "gHotSpotVMTypeEntryTypeNameOffset" in any of the known library names (libjvm.so, libjvm_g.so, gamma_g)
        at sun.jvm.hotspot.HotSpotTypeDataBase.lookupInProcess(HotSpotTypeDataBase.java:388)
        at sun.jvm.hotspot.HotSpotTypeDataBase.getLongValueFromProcess(HotSpotTypeDataBase.java:369)
        at sun.jvm.hotspot.HotSpotTypeDataBase.readVMTypes(HotSpotTypeDataBase.java:102)
        at sun.jvm.hotspot.HotSpotTypeDataBase.<init>(HotSpotTypeDataBase.java:85)
        at sun.jvm.hotspot.bugspot.BugSpotAgent.setupVM(BugSpotAgent.java:568)
        at sun.jvm.hotspot.bugspot.BugSpotAgent.go(BugSpotAgent.java:494)
        at sun.jvm.hotspot.bugspot.BugSpotAgent.attach(BugSpotAgent.java:332)
        at sun.jvm.hotspot.tools.Tool.start(Tool.java:163)
        at sun.jvm.hotspot.tools.HeapDumper.main(HeapDumper.java:77)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at sun.tools.jmap.JMap.runTool(JMap.java:179)
        at sun.tools.jmap.JMap.main(JMap.java:110)
Debugger attached successfully.

可能是什么问题?不重启进程能否解决(重启后bug可能会消失,所以我想避免它)。

【问题讨论】:

  • 更多细节:这个问题也出现在其他工具上,比如 jstack。 Java 版本为 1.6.0.10-64。系统是 Linux SUSE 10 x86_64 我从与运行该应用程序的相同的 java 安装中运行 jmap,并且使用相同的用户。

标签: java heap-dump jmap


【解决方案1】:

可能是什么问题?不重启进程能否解决(重启后bug可能会消失,所以我想避免它)。

冒着陈述显而易见的风险......

如果由于打开的连接过多而无法与调试器连接,那可能也是您要查找的错误的根源。

尝试使用操作系统级别的实用程序来找出进程当前打开了哪些文件/套接字/等。你给你一些线索告诉你从哪里开始寻找。如果这还不够,请在您的代码库中搜索打开文件/套接字的所有位置,并检查它们以确保它们有一个封闭的try / finally,它将始终关闭文件/套接字。

【讨论】:

  • 我可以看到(某种)打开了哪些套接字,并且确实提供了一些有关问题的线索,但我仍然想要全貌,也许在这种情况下不可能做到这一点。感谢您的帮助。
【解决方案2】:

您可以使用 Sun 6 JDK 中的 visualvm 进行连接吗?它使用了一种不同的方法,可以让你学到很多东西——这可能就足够了——但它不是一个调试器。

【讨论】:

  • visualvm 工作,但没有给我任何有用的信息。我一直在寻找堆转储。
  • 根据download-llnw.oracle.com/javase/6/docs/technotes/guides/…,它可以为本地应用程序创建堆转储。
  • 它仍然失败。也许这个过程被卡住了,所以无法检索到这些信息。我将不得不处理我能收集到的信息。谢谢大家!
  • 我认为您认为它被卡住是正确的。稍后的建议是建立一个日志机制,以便您至少可以看到当时发生的死亡事件。在文件中或可从 visualvm 访问的位置中。
【解决方案3】:

对于 Sun Jvm: 你可以试试新的

HotSpotDiagnostic().dumpHeap("d:\\HeapDump1",true);

如果 HotSpotDiagnostic 类在编译时不可见,则 您可以将具有 HotSpotDiagnosticMXBean.class 的 rt.jar 复制到其他位置。使用“添加外部 jar”在构建路径中引用复制的 jar。这允许您创建对象并获取堆转储。

【讨论】:

    猜你喜欢
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 2012-01-08
    • 2021-04-20
    • 2011-06-07
    • 2015-09-04
    相关资源
    最近更新 更多