在未捕获的exception上生成Java堆转储
当未捕获的exception被触发时,我尝试生成堆转储。 我尝试使用jmap,但因为当exception发生时进程已完成,这是不可能的。
使用UncaughtExceptionHandler也不是选项,因为我只有执行程序的二进制文件。
谁能帮我?
编辑:通过命令行或类似方法提供该技术非常重要,因为我需要自动执行此操作。 使用GUI是没有选择的
尝试将您的处理放入deamon线程。 这样您就可以使用内存分析工具访问它。 JVisualVM是一个JDK工具,您可以在JAVA_HOME \ bin中找到它。
还有另一种方法,称为转储分析器。 您使用以下JVM参数运行应用程序:
-
-XX:+ HeapDumpOnOutOfMemoryError
-
-XX:HeapDumpPath = “your_path”
但只有在出现OutOfMemoryError时才会使用此选项。 尝试查找是否可以为任何性能生成转储。
另一个优秀的基于Eclipse的工具是MemoryAnalyzer
这可以通过JVMTI代理实现,该代理将侦听VMDeath事件,然后使用JMM接口启动堆转储。
以下是此类JVMTI代理的示例源代码:
#include #include #include #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
如果您希望处理未捕获的exception而不是等待VMDeath,您可以使用类似的技术来安装Exception事件的回调。 在这里看一个例子。
我想建议Java Visual VM 。 它可以动态连接。 我发现它很有用。 你可能想尝试一下。