2014-11-07 8 views
8

जावा में थ्रेड डंप उत्पन्न करने के कई तरीके हैं।क्या JVMTI का उपयोग करके आवधिक जावा थ्रेड डंप उत्पन्न करने का कोई तरीका है?

मैं इसे चलाने के लिए JVMTI (सी एपीआई) का उपयोग करना चाहता हूं, ताकि चल रहे JVM पर इसके प्रदर्शन प्रभाव का मूल्यांकन किया जा सके। (मुझे जेस्टैक और जेएमएक्स के बारे में पता है; यह सवाल आमतौर पर थ्रेड डंप प्राप्त करने के बारे में नहीं है, लेकिन JVMTI एपीआई का उपयोग करने के बारे में)।

मैं अपना कोड this blog post से बंद कर रहा हूं। वहां, जावा एजेंट सिग्क्विट सिग्नल से जुड़ा हुआ है। मैं इससे बचना चाहता हूं, क्योंकि यह वही सिग्नल है जो जेवीएम स्टडआउट पर थ्रेड डंप लिखने के लिए उपयोग करता है। मैं उस डुप्लिकेट से बचना चाहता हूं।

दूसरे शब्दों में, मैं या तो एक अलग सिग्नल से जोड़ना चाहता हूं, या एजेंट को समय-समय पर थ्रेड डंप उत्पन्न करने का तरीका ढूंढना चाहता हूं।

+0

jvmtiEventCallbacks में से कोई भी घटना उपयुक्त नहीं दिखती है (जब तक आप DataDumpRequestion का उपयोग नहीं करना चाहते हैं, लेकिन यदि आपने किया, तो आप यहां नहीं पूछेंगे :))। ऐसा लगता है कि आप अपने एजेंट को 'GetStackTrace' को सीधे कॉल करने से सबसे अच्छे हैं। क्या कोई कारण है कि आप ऐसा नहीं कर सकते? –

+0

@ पॉल-हिक्स, क्या आप इस मामले में jvm से कैसे संलग्न होंगे इस पर एक लिंक या कोड पोस्ट कर सकते हैं? – Ovesh

+0

आपने एजेंट को डीएल या एसएसओ को अपने जेवीएम के-गैन्टपाथ में रखा है या इसे एगेंटलिब के रूप में परिभाषित किया है। [इस उत्तर] पर एक नज़र डालें (http://stackoverflow.com/a/173447/3195526) या [आईबीएम के परिचय पृष्ठ] (http://publib.boulder.ibm.com/infocenter/realtime/v2r0/index। jsp? topic =% 2Fcom.ibm.rt.doc.20% 2Fdiag% 2Ftools% 2Fjvmti.html)। क्या यह आप जानना चाहते थे? क्या मुझे इसे एक जवाब में बदलना चाहिए? –

उत्तर

2

वहां, जावा एजेंट सिग्क्विट सिग्नल से जुड़ा हुआ है। मैं इससे बचना चाहता हूं, क्योंकि यह वही सिग्नल है जो जेवीएम स्टडआउट पर थ्रेड डंप लिखने के लिए उपयोग करता है। मैं उस डुप्लिकेट से बचना चाहता हूं।

बस अपने कोड से निम्नलिखित अंश को निकाल दें

/* Set callbacks and enable event notifications */ 
memset(&callbacks, 0, sizeof(callbacks)); 
callbacks.DataDumpRequest = &dumpThreadInfo; 
err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); 
CHECK_JVMTI_ERROR(jvmti, err); 
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,JVMTI_EVENT_DATA_DUMP_REQUEST, NULL); 
CHECK_JVMTI_ERROR(jvmti, err); 

मैं या तो एक अलग संकेत

Here is कागज करने के लिए अटैच करना चाहते हैं, कि एक सा पुराना है, लेकिन जानकारी अभी भी प्रासंगिक होनी चाहिए।

बस कैसे एक संकेत

import sun.misc.Signal; 
import sun.misc.SignalHandler; 

public class ThreadDumpSignalHandler implements SignalHandler { 
    private volatile SignalHandler old; 
    private ThreadDumpSignalHandler() { 

    } 
    public static void register(String sigName) { 
     ThreadDumpSignalHandler h = new ThreadDumpSignalHandler(); 
     h.old = Signal.handle(new Signal(sigName), h) 
    } 
    public void handle(Signal sig) { 
     threadDump(); 

     if(old != null && old != SIG_DFL && old != SIG_IGN) { 
      old.handle(sig); 
     } 
    } 
    // call your own threadDump native method. 
    // note that in the implementation of this method you are able to access jvmtiEnv from *gdata (see below) 
    private native void threadDump(); 
} 

ThreadDumpSignalHandler.register("INT"); 
आप पूरी तरह से देशी संकेत हैंडलर लिख सकते हैं कारण के

से निपटने क्या करने का एक नमूना (कृपया ध्यान दें कि मैं यह परीक्षण नहीं किया, यह सिर्फ एक विचार है कि काम करना चाहिए है)

static sighandler_t old_handler; 
static void thread_dump_handler(int signum) { 
    if(gdata && gdata->jvmti) { 
     ... get thread dump 
    } 

    if(old_handler) { 
     old_handler(signum); 
    } 
} 

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) { 
    old_handler = signal(SIGINT, thread_dump_handler); 

    ... 
} 

या एजेंट समय-समय पर एक धागा डंप उत्पन्न करने के लिए के लिए एक रास्ता खोजने।

अपने नमूना में वैश्विक है * GData

typedef struct { 
    /* JVMTI Environment */ 
    jvmtiEnv  *jvmti; 
    jboolean  vm_is_started; 
    /* Data access Lock */ 
    jrawMonitorID lock; 
} GlobalAgentData; 

static GlobalAgentData *gdata; 

... हां, तो बस किसी भी समय आप चाहते हैं (घड़ी कॉलबैक, आदि)

+0

'* gdata' से' * jvmti' सुरक्षित हो रहा है? मैं इसके बारे में इतना यकीन नहीं कर रहा हूं, लेकिन मैं इसे आज़मा सकता हूं। – Ovesh

+1

यह सुरक्षित होना चाहिए। कम से कम आप हमेशा [RawMonitorEnter] का उपयोग कर सकते हैं (https://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#RawMonitorEnter) और [RawMonitorExit] (https://docs.oracle.com /javase/7/docs/platform/jvmti/jvmti.html#RawMonitorExit) gdata-> लॉक के साथ, लेकिन मुझे नहीं लगता कि यह वास्तव में तब तक जरूरी है जब तक आप gdata-> jvmti को एक साथ नहीं पहुंचने जा रहे हैं। – szhem

+1

इसके अलावा, आप [RunAgentThread] (https://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#RunAgentThread) के माध्यम से एक थ्रेड बना सकते हैं। थ्रेड का [प्रारंभ कार्य] (https://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#jvmtiStartFunction) jvmtiEnv को इसके पहले पैरा के रूप में स्वीकार करता है। तो आप इस मूल रूप से बनाए गए धागे के भीतर से आवधिक थ्रेड डंप कर सकते हैं। * Jvmti का उपयोग कर – szhem

-2

कोई नहीं पर वहाँ से jvmtiEnv प्राप्त jvmtiEventCallbacks में घटनाओं के उपयुक्त दिखते हैं (जब तक आप DataDumpRequestion का उपयोग नहीं करना चाहते हैं, लेकिन यदि आपने किया है, तो आप यहां नहीं पूछेंगे: ठीक है, तो यह बहुत अधिक है कि मैंने अब तक जेवीएम से जुड़ा हुआ है (मामूली मतभेदों के साथ)। तो मुझे लगता है कि मुझे अगले प्रश्न पर लाता है: मैं एक पीओ कैसे प्राप्त करूं GetbackTrace को कॉल करने के लिए, यदि कॉलबैक से नहीं है, तो jvmtiEnv में अंतर करें? बिंदु आप जावा उड़ान रिकॉर्डर का उपयोग कर सकते, टी कॉल करने के लिए

2

अपने लक्ष्य को समय-समय पर धागा डंप इकट्ठा करने के लिए है, तो यह है कि के ओरेकल JDK 7 अद्यतन 40 (7u40) रिहाई के साथ शुरू Java Mission Controller

का हिस्सा है, जावा मिशन कंट्रोल हॉटस्पॉट जेवीएम के साथ बंडल किया गया है।

0

आपके द्वारा उद्धृत ब्लॉग एंट्री में आपको JVMTI प्लंबिंग के लिए सबसे अधिक आवश्यकता है। आप gdata से JVMTIenv का उपयोग कर सकते हैं। वह कानूनी है। सुनिश्चित करें कि क्या आप जेएनआई कॉल को अपने वर्तमान थ्रेड के लिए उचित जेएनआईएनवी रखने के लिए कॉल कर रहे हैं।

अब आपको अपनी कार्रवाई करने के लिए अधिसूचित होने के लिए एक तरीका जोड़ने की आवश्यकता है (उदाहरण: थ्रेड डंप)। एक सॉकेट पर सुनते हुए एक धागे को स्पिन करें, inotify का उपयोग करता है, नाममात्र नाम, आदि .. - कुछ जो आप बाहर से पोक कर सकते हैं।

फिर आप फिट होने पर अपने ईवेंट हैंडलर लूप से dumpThreadInfo() को कॉल कर सकते हैं।

संबंधित मुद्दे