जावा थ्रेड डंप का विश्लेषण कैसे करें?


100

मैं जावा के बारे में अधिक समझने की कोशिश कर रहा हूं, विशेष रूप से स्मृति प्रबंधन और थ्रेड्स के बारे में। इस कारण से मुझे हाल ही में थ्रेड डंप को देखने में रुचि मिली है।

यहाँ विज़ुअलम, जो जावा के लिए एक बिल्ट-इन टूल का उपयोग करके वेब ऐप से कुछ पंक्तियाँ ली गई हैं:

"Finalizer" daemon prio=8 tid=0x02b3d000 nid=0x898 in Object.wait() [0x02d0f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x27ef0288> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
    - locked <0x27ef0288> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

   Locked ownable synchronizers:
    - None

"Reference Handler" daemon prio=10 tid=0x02b3b800 nid=0x494 in Object.wait() [0x02cbf000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x27ef0310> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:485)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
    - locked <0x27ef0310> (a java.lang.ref.Reference$Lock)

पहले मेरे पास कुछ चर नामों के बारे में प्रश्न हैं:

  • tid और nid का क्या अर्थ है?
  • Object.wait के बाद चौकोर कोष्ठक में आकृति क्या है?

फिर स्टैक ट्रेस के लिए ही:

  • इसका मतलब क्या है <.....> (एक java.lang ....) पर प्रतीक्षा करना और <..> में नंबर क्या है
  • इसका क्या अर्थ है कि लॉक किया गया <.....> (एक java.lang ....) एक ही प्रश्न, क्या है <..> में

मुझे लगा कि लॉक शब्द किसी प्रतीक्षा की स्थिति में संबंधित था, हालांकि, मैं गलत था। वास्तव में, मैं सोच रहा हूं कि लॉक को तीन बार क्यों दोहराया जाता है, लेकिन धागा रन करने योग्य स्थिति में है जैसा कि एक ही डंप में देखा गया है:

"Thread-0" prio=6 tid=0x02ee3800 nid=0xc1c runnable [0x03eaf000]
   java.lang.Thread.State: RUNNABLE
    at java.io.FileInputStream.readBytes(Native Method)
    at java.io.FileInputStream.read(FileInputStream.java:199)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
    - locked <0x23963378> (a java.io.BufferedInputStream)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
    - locked <0x23968450> (a java.io.InputStreamReader)
    at java.io.InputStreamReader.read(InputStreamReader.java:167)
    at java.io.BufferedReader.fill(BufferedReader.java:136)
    at java.io.BufferedReader.readLine(BufferedReader.java:299)
    - locked <0x23968450> (a java.io.InputStreamReader)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)
    at org.codehaus.plexus.util.cli.StreamPumper.run(StreamPumper.java:145)

तब सब से आखिरी, यह उनमें से सबसे खराब था:

"CompilerThread0" daemon prio=10 tid=0x02b81000 nid=0x698 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

यह धागा रन करने योग्य स्थिति में है, लेकिन यह स्थिति पर प्रतीक्षा कर रहा है। क्या स्थिति है और 0x00000 क्या है?

थ्रेड क्लास के किसी भी सबूत के बिना स्टैक ट्रेस इतना छोटा क्यों है?

यदि आप मेरे सभी सवालों का जवाब दे सकते हैं तो मैं बहुत आभारी रहूंगा।

धन्यवाद

जवाबों:


113

TID आईडी है और NID है: मूल धागा आईडी। यह आईडी अत्यधिक प्लेटफार्म पर निर्भर है। यह jstack थ्रेड डंप में NID है। विंडोज पर, यह एक प्रक्रिया के भीतर बस ओएस-स्तर थ्रेड आईडी है। लिनक्स और सोलारिस पर, यह थ्रेड का पीआईडी ​​है (जो बदले में एक हल्के वजन की प्रक्रिया है)। Mac OS X पर, इसे देशी pthread_t मान कहा जाता है।

इस लिंक पर जाएं: जावा-लेवल थ्रेड आईडी : परिभाषा के लिए और इन दोनों शब्दों की आगे की व्याख्या।

आईबीएम की साइट पर मुझे यह लिंक मिला: थ्रेड डंप की व्याख्या कैसे करें । जो इसे अधिक विस्तार से कवर करता है:

यह बताता है कि उस प्रतीक्षा का क्या मतलब है: एक ताला एक साझा संसाधन तक पहुँचने से एक इकाई को रोकता है। जावा ™ की प्रत्येक वस्तु में एक संबद्ध ताला होता है (एक सिंक्रनाइज़ ब्लॉक या विधि का उपयोग करके प्राप्त किया जाता है)। JVM के मामले में, धागे JVM में विभिन्न संसाधनों के लिए प्रतिस्पर्धा करते हैं और जावा ऑब्जेक्ट्स पर ताले लगाते हैं।

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

फिर यह आगे बढ़ता है:

हर वस्तु पर निगरानी रखने से बचने के लिए, जेवीएम आमतौर पर वर्ग या विधि खंड में एक ध्वज का उपयोग करता है ताकि यह इंगित किया जा सके कि आइटम बंद है। अधिकांश समय, कोड का एक टुकड़ा विवाद के बिना कुछ बंद खंड को पार कर जाएगा। इसलिए, कोड के इस टुकड़े की सुरक्षा के लिए संरक्षक ध्वज पर्याप्त है। इसे फ्लैट मॉनिटर कहा जाता है। हालाँकि, यदि कोई अन्य थ्रेड लॉक किए गए कुछ कोड तक पहुँच प्राप्त करना चाहता है, तो एक वास्तविक विवाद उत्पन्न हो गया है। JVM को अब दूसरे थ्रेड को पकड़ने के लिए मॉनीटर ऑब्जेक्ट को बनाना (या बढ़ाना) चाहिए और कोड सेक्शन तक पहुंच को समन्वय करने के लिए एक सिग्नलिंग तंत्र की व्यवस्था करनी चाहिए। इस मॉनिटर को अब फुलाया हुआ मॉनिटर कहा जाता है।

यहाँ आप थ्रेड डंप की तर्ज पर क्या देख रहे हैं, इसकी अधिक गहराई से व्याख्या की गई है। एक जावा थ्रेड ऑपरेटिंग सिस्टम के एक देशी थ्रेड द्वारा कार्यान्वित किया जाता है। प्रत्येक धागे को बोल्ड में एक लाइन द्वारा दर्शाया जाता है जैसे:

"थ्रेड -1" (TID: 0x9017A0, sys_thread_t: 0x23EAC8, state: R, देशी आईडी: 0x6E4) prio = 5

* निम्नलिखित 6 आइटम इस बात की व्याख्या करते हैं कि मैंने उन्हें उदाहरण से, कोष्ठक में मानों से मिलान किया है:]

  1. नाम [ थ्रेड -1 ],
  2. पहचानकर्ता [ 0x9017A0 ],
  3. JVM डेटा संरचना पता [ 0x23EAC8 ],
  4. वर्तमान स्थिति [ आर ],
  5. देशी धागा पहचानकर्ता [ 0x6E4 ],
  6. और प्राथमिकता [ 5 ]।

"प्रतीक्षा करें" प्रतीत होता है कि डेम थ्रेड jvm से जुड़ा हुआ है न कि एप्लिकेशन थ्रेड पियर्स। जब आपको "Object.wait ()" में मिलता है, तो इसका मतलब है कि डेमॉन थ्रेड, "फाइनल", यहां एक ऑब्जेक्ट पर लॉक के बारे में एक अधिसूचना पर इंतजार कर रहा है, इस मामले में यह आपको दिखाता है कि यह किस अधिसूचना पर इंतजार कर रहा है: "- <0x27ef0288> (a java.lang.ref.eferenceQueue $ Lock) पर प्रतीक्षा की जा रही है "

ReferenceQueue की परिभाषा है: संदर्भ कतार, जिसमें पंजीकृत संदर्भ ऑब्जेक्ट्स उपयुक्त कचरा परिवर्तन का पता चलने के बाद कचरा कलेक्टर द्वारा जोड़ा जाता है।

फाइनल थ्रेड चलाता है इसलिए कचरा संग्रह किसी वस्तु से जुड़े संसाधनों को साफ करने के लिए संचालित होता है। अगर मैं इसे शालीनता से देख रहा हूं, तो फ़ाइनलीज़र इस ऑब्जेक्ट को लॉक नहीं कर सकता: java.lang.ref.eferenceQueue.remove (ReferenceQueue.java:118) क्योंकि जावा ऑब्जेक्ट एक विधि चल रहा है, इसलिए फ़ाइनलीज़र थ्रेड है उस वस्तु को तब तक बंद रखा जाता है जब तक वह चालू कार्य के साथ समाप्त नहीं हो जाती।

इसके अलावा, फ़ाइनलीज़र केवल मेमोरी को पुनः प्राप्त करने की तलाश में नहीं है, यह संसाधनों की सफाई के लिए उससे अधिक शामिल है। मुझे इस पर और अधिक अध्ययन करने की आवश्यकता है, लेकिन यदि आपके पास किसी ऑब्जेक्ट के तरीकों से संबंधित फाइलें खुली हुई हैं, सॉकेट्स आदि हैं, तो फ़ाइनलज़र उन वस्तुओं को भी मुक्त करने का काम करने जा रहा है।

थ्रेड डंप में Object.wait के बाद चौकोर कोष्ठक में आकृति क्या है?

यह थ्रेड के लिए स्मृति में एक सूचक है। यहाँ एक अधिक विस्तृत वर्णन है:

C.4.1 थ्रेड जानकारी

थ्रेड अनुभाग का पहला भाग उस थ्रेड को दिखाता है जो घातक त्रुटि को उकसाता है, इस प्रकार है:

Current thread (0x0805ac88):  JavaThread "main" [_thread_in_native, id=21139]
                    |             |         |            |          +-- ID
                    |             |         |            +------------- state
                    |             |         +-------------------------- name
                    |             +------------------------------------ type
                    +-------------------------------------------------- pointer

थ्रेड पॉइंटर Java VM आंतरिक थ्रेड संरचना का सूचक है। जब तक आप एक लाइव जावा वीएम या कोर फ़ाइल डिबगिंग नहीं कर रहे हैं तब तक यह आम तौर पर कोई दिलचस्पी नहीं है।

यह अंतिम विवरण आया है: हॉटस्पॉट वीएम के साथ जावा एसई 6 के लिए समस्या निवारण गाइड

यहाँ थ्रेड्स पर कुछ और लिंक दिए गए हैं:


11

@James Drinkard के शानदार जवाब के लिए आगे:

ध्यान दें कि, अंतर्निहित कार्यान्वयन के आधार पर, java.lang.Thread.State एक देशी विधि में अवरुद्ध एक धागे के रूप में रिपोर्ट किया जा सकता है RUNNABLE, जहाँA thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

यह पता चला है कि यह विवरण भी एक ओएस कॉल में अवरुद्ध किया जा रहा है जैसे कि पोल या रीड ऑपरेशन - संभवतः क्योंकि कोई गारंटी नहीं है कि जेवीएम को पता चल सकता है कि जब एक देशी विधि कॉल ओएस स्तर पर अवरुद्ध हो गई है।

जेवीएम थ्रेड डंप की कई चर्चाएँ जो मैंने देखी हैं या तो इस संभावना को पूरी तरह से नज़रअंदाज़ कर देती हैं, या निहितार्थों पर विचार किए बिना इस पर स्पष्ट रूप से ध्यान केंद्रित करती हैं - जिनमें से कम से कम यह नहीं है कि निगरानी उपकरण भ्रामक रूप से रिपोर्ट कर सकते हैं कि ऐसे कई धागे 'चल रहे' हैं, और इसके अलावा वे सभी 100% पर चल रहे हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.