Generate Java Heap Dump on uncaught Exception

前端 未结 3 2012
没有蜡笔的小新
没有蜡笔的小新 2020-12-09 23:18

I try to generate a Heap Dump when a uncaught exception is fired. I tried using jmap, but because the process is finished when the exception happens this is not possible.

相关标签:
3条回答
  • 2020-12-09 23:48

    Try to put your processing into a deamon thread. this way you can access it with memory analysis tools. JVisualVM is a JDK tool you can find it in your JAVA_HOME\bin.

    There are also another way, called dump analyser. You run your application with these JVM parameters :

    • -XX:+HeapDumpOnOutOfMemoryError

    • -XX:HeapDumpPath="your_path"

    But this is used only if you have an OutOfMemoryError. Try to find if it's possible to generate the dump for any performance.

    Another good eclipse based tool is MemoryAnalyzer

    0 讨论(0)
  • 2020-12-09 23:54

    I would like to suggest Java Visual VM. It can connect dynamically. I found it useful. You might want to give a try.

    0 讨论(0)
  • 2020-12-10 00:00

    This can be achieved with JVMTI agent that will listen to VMDeath event and then use JMM interface to initiate Heap Dump.

    Here is a sample source code of such JVMTI agent:

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

    After you've compiled it into the shared library (libdump.so) run Java with -agentpath option:

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

    If you wish to handle uncaught exceptions instead of waiting for VMDeath, you may use similar technique to install callback for Exception event. Look here for an example.

    0 讨论(0)
提交回复
热议问题