2014-05-09 5 views
5

पर काउंटर अपवाद है, मुझे आश्चर्य है कि आवेदन कोड बदलने के बिना जेवीएम स्तर पर होने वाले हर अपवाद को लॉग करना संभव है? प्रत्येक अपवाद से मेरा मतलब है पकड़ा गया और अपरिपक्व अपवाद ... मैं बाद में उन लॉग का विश्लेषण करना चाहता हूं और उन्हें अपवाद प्रकार (कक्षा) द्वारा समूहित करना चाहता हूं और बस प्रकार के अपवादों की गणना करना चाहता हूं। मैं हॉटस्पॉट का उपयोग कर रहा हूं;)जावा अपवादों JVM HotSpot

शायद ऐसा करने का स्मार्ट क्यों है? उदाहरण के लिए किसी भी मुफ्त प्रोफाइलर द्वारा (आपकेकिट में यह है लेकिन यह मुफ़्त नहीं है)? मुझे लगता है कि जेआरॉकिट में प्रबंधन कंसोल में अपवाद काउंटर है, लेकिन हॉटस्पॉट के लिए कुछ भी ऐसा नहीं दिख रहा है।

+0

डिफ़ॉल्ट अपवादों को stderr पर भेजा जाता है; इसलिए यदि आप stderr को रीडायरेक्ट करते हैं तो आपको अपने अपवादों को कहीं भी प्राप्त करना चाहिए जहां आपने रीडायरेक्ट किया है। – fge

+0

@fge लेकिन फिर वह अपवाद नहीं देख पाएंगे जहां पकड़ा गया और मुद्रित नहीं किया गया था। –

+0

@ अब्बार्ड-माइंड आह हाँ, मैंने उस भाग को नहीं देखा ... ठीक है, कोड को मापने से कम मुझे – fge

उत्तर

5

मुझे विश्वास है कि ऐसा करने के लिए नि: शुल्क उपकरण हैं, लेकिन यहां तक ​​कि अपना स्वयं का टूल बनाना आसान है। JVMTI मदद करेगा।

यहाँ एक सरल JVMTI एजेंट मैं सभी अपवादों को पता लगाने के लिए किया जाता है:

#include <jni.h> 
#include <jvmti.h> 
#include <string.h> 
#include <stdio.h> 

void JNICALL ExceptionCallback(jvmtiEnv* jvmti, JNIEnv* env, jthread thread, 
           jmethodID method, jlocation location, jobject exception, 
           jmethodID catch_method, jlocation catch_location) { 
    char* class_name; 
    jclass exception_class = (*env)->GetObjectClass(env, exception); 
    (*jvmti)->GetClassSignature(jvmti, exception_class, &class_name, NULL); 
    printf("Exception: %s\n", class_name); 
} 


JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { 
    jvmtiEnv* jvmti; 
    jvmtiEventCallbacks callbacks; 
    jvmtiCapabilities capabilities; 

    (*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION_1_0); 

    memset(&capabilities, 0, sizeof(capabilities)); 
    capabilities.can_generate_exception_events = 1; 
    (*jvmti)->AddCapabilities(jvmti, &capabilities); 

    memset(&callbacks, 0, sizeof(callbacks)); 
    callbacks.Exception = ExceptionCallback; 
    (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); 
    (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL); 

    return 0; 
} 

इसके इस्तेमाल के लिये दी गई स्रोत कोड से किसी साझा लाइब्रेरी (.so) बनाने के लिए, और -agentpath विकल्प के साथ जावा चलाएँ:

java -agentpath:libextrace.so MyApplication 

यह stdout पर सभी अपवाद वर्ग नाम लॉग करेगा। ExceptionCallback को एक धागा, एक विधि और एक स्थान भी प्राप्त होता है जहां अपवाद होता है, ताकि आप अधिक विवरण मुद्रित करने के लिए कॉलबैक बढ़ा सकें।

+0

मुझे आश्चर्य है कि जावा उपकरण के साथ समान कार्यक्षमता प्राप्त करना संभव है? (java.lang.instrument) – user1058831

+2

@ user1058831 इंस्ट्रुमेंटेशन आपको जावा बाइटकोड को संशोधित करने की अनुमति देता है, लेकिन सभी अपवाद 'एथ्रो' बाइटकोड से नहीं आते हैं। उनमें से कुछ देशी पुस्तकालय कोड द्वारा फेंक दिए जाते हैं और कुछ को पूरी तरह से जेवीएम द्वारा फेंक दिया जाता है। उपकरण द्वारा सबसे नज़दीकी चीज जो आप कर सकते हैं शायद पीटर के 'थ्रोबल' कन्स्ट्रक्टर को संशोधित करने का सुझाव है। एक ही समय में JVMTI एजेंट स्वचालित रूप से सभी मामलों को संभाल लेगा। – apangin