2014-05-13 28 views
3

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

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

任何人都可以帮助我吗?

编辑:重要的是,该技术可通过命令行或类似的,因为我需要自动化这一点。使用GUI是没有选择的

+0

未被谁抓到? – fge

+0

在“导致程序崩溃”的意义上未被捕获。 – user1839433

+1

@assylias这将生成堆栈的线程转储。我想要堆转储 – user1839433

回答

-1

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

+0

这看起来很有用,但它有一个cli?我需要将它集成到系统中以自动探索堆转储 – user1839433

+0

是的。继续使用它。 – Ashish

+0

你能告诉我在哪里可以找到更多关于这方面的信息吗?我找不到任何东西。只是与GUI的东西 – user1839433

1

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

还有另一种方法,称为转储分析器。你跟这些JVM参数运行应用程序:

  • -XX:+ HeapDumpOnOutOfMemoryError

  • -XX:HeapDumpPath = “your_path”

但是,如果你有这只是用来OutOfMemoryError异常。尝试查找是否可以为任何性能生成转储。

另一个很好的基于Eclipse的工具是MemoryAnalyzer

0

这可以用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,则可以使用类似的技术为Exception事件安装回调。以here为例。

+0

虽然也许不完全是OP想要的,这是一个很棒的答案。 – Qix