【问题标题】:Generate Java Heap Dump on uncaught Exception在未捕获的异常上生成 Java 堆转储
【发布时间】:2014-07-01 05:02:18
【问题描述】:

当触发未捕获的异常时,我尝试生成堆转储。我尝试使用 jmap,但是因为当异常发生时进程已经完成,所以这是不可能的。

使用 UncaughtExceptionHandler 也不是选项,因为我只有所执行程序的二进制文件。

谁能帮帮我?

编辑:通过命令行或类似方法可以使用该技术很重要,因为我需要将其自动化。使用 GUI 是不行的

【问题讨论】:

  • 在“导致程序崩溃”的意义上未捕获。
  • @assylias 这会生成堆栈的线程转储。我想要堆转储

标签: java jvm heap-dump


【解决方案1】:

这可以通过JVMTI 代理来实现,该代理将侦听VMDeath 事件,然后使用JMM interface 启动堆转储。

以下是此类 JVMTI 代理的示例源代码:

#include <jvmti.h>
#include <string.h>
#include <stdio.h>
#include "jmm.h"

JNIEXPORT void* JNICALL JVM_GetManagement(jint version);

void JNICALL VMDeath(jvmtiEnv* jvmti, JNIEnv* jni) {
    JmmInterface* jmm = (JmmInterface*) JVM_GetManagement(JMM_VERSION_1_0);
    if (jmm == NULL) {
        printf("Sorry, JMM is not supported\n");
    } else {
        jstring path = (*jni)->NewStringUTF(jni, "dump.hprof");
        jmm->DumpHeap0(jni, path, JNI_TRUE);
        printf("Heap dumped\n");
    }
}

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
    jvmtiEnv* jvmti;
    (*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION_1_0);

    jvmtiEventCallbacks callbacks;
    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.VMDeath = VMDeath;
    (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
    (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL);

    return 0;
}

将其编译到共享库 (libdump.so) 后,使用 -agentpath 选项运行 Java:

java -agentpath:/path/to/libdump.so MainClass

如果您希望处理未捕获的异常而不是等待 VMDeath,您可以使用类似的技术为异常事件安装回调。以here 为例。

【讨论】:

  • 虽然可能不完全是 OP 想要的,但这是一个很棒的答案。
  • 我发现要编译上面的例子,需要将它与 jvm.dll/libjvm.so 链接起来
【解决方案2】:

尝试将您的处理放入一个守护线程。这样您就可以使用内存分析工具访问它。 JVisualVM 是一个 JDK 工具,您可以在 JAVA_HOME\bin 中找到它。

还有另一种方式,称为转储分析器。您使用这些 JVM 参数运行您的应用程序:

  • -XX:+HeapDumpOnOutOfMemoryError

  • -XX:HeapDumpPath="your_path"

但这仅在您有 OutOfMemoryError 时使用。尝试查找是否可以为任何性能生成转储。

另一个不错的基于 Eclipse 的工具是 MemoryAnalyzer

【讨论】:

    【解决方案3】:

    我想推荐Java Visual VM。它可以动态连接。我发现它很有用。您可能想尝试一下。

    【讨论】:

    • 这看起来很有用,但它有 cli 吗?我需要将其集成到系统中以自动探索堆转储
    • 是的。继续使用它。
    • 您能告诉我在哪里可以找到有关此的更多信息吗?我什么也找不到。只需使用 GUI 即可
    猜你喜欢
    • 2013-05-01
    • 1970-01-01
    • 2010-11-25
    • 2012-10-26
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多