Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate Java Heap Dump on uncaught Exception

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.

Using a UncaughtExceptionHandler is no option either, because I only have the binaries of the programs that is executed.

Can anyone help me?

EDIT: It is important that the technique is available through a command line or similar, because I need to automated this. Using a GUI is no option

like image 523
user1839433 Avatar asked May 13 '14 13:05

user1839433


People also ask

How do I make an automatic heap dump?

In order to capture a heap dump automatically, we need to add the HeapDumpOnOutOfMemoryError command-line option that generates a heap dump when a java. lang. OutOfMemoryError is thrown.

How do I manually take a heap dump?

Start the administrative console. In the navigation pane, click Troubleshooting > Java dumps and cores. Select the server_name for which you want to generate the heap dump. Click Heap dump to generate the heap dump for your specified server.

What is XX HeapDumpPath?

Syntax. -XX:HeapDumpPath=<path> where <path> is the directory to which all dump types are written. This directory path is prefixed to the path of all non-absolute dump file names, including the file names for the default dump agents.


1 Answers

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.

like image 116
apangin Avatar answered Oct 04 '22 10:10

apangin