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