有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

jvm在未捕获异常时生成Java堆转储

我尝试在触发未捕获异常时生成堆转储。我尝试使用jmap,但由于异常发生时流程已完成,因此这是不可能的

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

有人能帮我吗

编辑:这项技术通过命令行或类似的方式提供是很重要的,因为我需要实现自动化。使用GUI是没有选择的


共 (3) 个答案

  1. # 1 楼答案

    试着把你的处理过程放到一个执事线程中。通过这种方式,你可以使用内存分析工具来访问它。JVisualVM是一个JDK工具,您可以在JAVA_HOME\bin中找到它

    还有另一种方法,称为转储分析器。使用以下JVM参数运行应用程序:

    • -XX:+HeapDumpOnOutOfMemoryError

    • -XX:HeapDumpPath=“你的路径”

    但只有当您有OutOfMemory错误时,才会使用此选项。尝试找出是否有可能为任何性能生成转储

    另一个好的基于eclipse的工具是MemoryAnalyzer

  2. # 2 楼答案

    我想建议Java Visual VM。它可以动态连接。我发现它很有用。你可能想试试

  3. # 3 楼答案

    这可以通过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的例子