當未捕獲異常被觸發時,我嘗試生成堆轉儲。我嘗試使用jmap,但因爲過程在異常發生時完成,所以這是不可能的。未捕獲異常時生成Java堆轉儲
使用UncaughtExceptionHandler也不是選項,因爲我只有執行的程序的二進制文件。
任何人都可以幫助我嗎?
編輯:重要的是,該技術可通過命令行或類似的,因爲我需要自動化這一點。使用GUI是沒有選擇的
當未捕獲異常被觸發時,我嘗試生成堆轉儲。我嘗試使用jmap,但因爲過程在異常發生時完成,所以這是不可能的。未捕獲異常時生成Java堆轉儲
使用UncaughtExceptionHandler也不是選項,因爲我只有執行的程序的二進制文件。
任何人都可以幫助我嗎?
編輯:重要的是,該技術可通過命令行或類似的,因爲我需要自動化這一點。使用GUI是沒有選擇的
我想建議Java Visual VM。它可以動態連接。我發現它很有用。你可能想嘗試一下。
這看起來很有用,但它有一個cli?我需要將它集成到系統中以自動探索堆轉儲 – user1839433
是的。繼續使用它。 – Ashish
你能告訴我在哪裏可以找到更多關於這方面的信息嗎?我找不到任何東西。只是與GUI的東西 – user1839433
嘗試將你的處理放入deamon線程。通過這種方式,您可以使用內存分析工具訪問它。 JVisualVM是一個JDK工具,您可以在JAVA_HOME \ bin中找到它。
還有另一種方法,稱爲轉儲分析器。你跟這些JVM參數運行應用程序:
-XX:+ HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath = 「your_path」
但是,如果你有這只是用來OutOfMemoryError異常。嘗試查找是否可以爲任何性能生成轉儲。
另一個很好的基於Eclipse的工具是MemoryAnalyzer
這可以用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爲例。
雖然也許不完全是OP想要的,這是一個很棒的答案。 – Qix
未被誰抓到? – fge
在「導致程序崩潰」的意義上未被捕獲。 – user1839433
@assylias這將生成堆棧的線程轉儲。我想要堆轉儲 – user1839433