tl JRE 1.8.0_91
उपयोग कर रहा हूँ; डॉ मुझे लगता है कि आप जी सी से संबंधित व्यवहार, जहां धागे किया जा रहा है में चल रहे हैं कचरा संग्रह की अनुमति देने के लिए प्रतीक्षा राज्य में डाल दिया।
मेरे पास पूरी सच्चाई नहीं है लेकिन मुझे अंतर्दृष्टि के कुछ टुकड़े प्रदान करने की उम्मीद है।
पहले यह समझने की बात यह है कि ब्रैकेट्स, [0x00007fe64df9a000]
में संख्या मॉनिटर का पता नहीं है। सभी धागे के लिए ब्रैकेट में संख्या को डंप में देखा जा सकता है, यहां तक कि थ्रेड जो चल रहे राज्य में हैं। संख्या भी बदलती नहीं है। अपने परीक्षण डंप से उदाहरण:
main" #1 prio=5 os_prio=0 tid=0x00007fe27c009000 nid=0x27e5c runnable [0x00007fe283bc2000]
java.lang.Thread.State: RUNNABLE
at Foo.main(Foo.java:12)
मैं क्या संख्या का मतलब है यकीन नहीं है, लेकिन this page संकेत यह है कि:
... जावा वी एम आंतरिक धागा संरचना करने के लिए सूचक। यह आमतौर पर कोई दिलचस्पी नहीं है जब तक कि आप लाइव जावा वीएम या कोर फ़ाइल को डिबग नहीं कर रहे हों।
हालांकि ट्रेस के प्रारूप में बताया गया है कि थोड़ा अलग है इसलिए मुझे यकीन नहीं है कि मैं सही हूं।
तरह से जब वास्तविक मॉनिटर के पता दिखाया गया है एक डंप दिखता है:
"qtp48612937-70" #70 prio=5 os_prio=0 tid=0x00007fbb845b4800 nid=0x133c waiting for monitor entry [0x00007fbad69e8000]
java.lang.Thread.State: BLOCKED (on object monitor)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:233)
- waiting to lock <0x00000005b8d68e90> (a java.lang.Object)
सूचना का पता लगाने में और उस पर नजर रखने के पता कोष्ठक में संख्या से भिन्न है waiting to lock
लाइन।
तथ्य यह है कि हम मॉनीटर के पते को नहीं देख सकते हैं यह इंगित करता है कि मॉनिटर केवल मूल कोड में मौजूद है।
दूसरा, इसमें शामिल जीसन कोड में कोई सिंक्रनाइज़ेशन नहीं है। कोड सिर्फ ArrayList
पर एक तत्व जोड़ता है (माना जाता है कि कोई बाइटकोड मैनिपुलेशन नहीं किया गया है और कम स्तर पर मछली पकड़ने वाला कुछ भी नहीं किया जा रहा है)। यानी, इस कॉल पर मानक सिंक्रनाइज़ेशन मॉनिटर के लिए प्रतीक्षा थ्रेड को देखना समझ में नहीं आता है।
मुझे some, indications मिला कि थ्रेड को मॉनिटर एंट्री की प्रतीक्षा के रूप में दिखाया जा सकता है जब बहुत सी जीसी चल रही है।
मैं एक साधारण परीक्षण कार्यक्रम में लिखा था सिर्फ एक सरणी सूची में तत्वों का एक बहुत जोड़ने के द्वारा पुन: पेश करने की कोशिश करने के लिए:
List<String> l = new ArrayList<>();
while (true) {
for (int i = 0; i < 100_100; i++) {
l.add("" + i);
}
l = new ArrayList<>();
}
तब मैं इस कार्यक्रम का धागा डंप ले लिया। कभी कभी मैं निम्नलिखित का पता लगाने में भाग:
"main" #1 prio=5 os_prio=0 tid=0x00007f35a8009000 nid=0x12448 waiting on condition [0x00007f35ac335000]
java.lang.Thread.State: RUNNABLE
at Foo.main(Foo.java:10) <--- Line of l.add()
जबकि ओ पी के निशान के समान नहीं है, यह जब कोई तुल्यकालन शामिल है एक धागा waiting on condition
के लिए दिलचस्प है। मैंने इसे एक छोटे ढेर के साथ अधिक बार अनुभव किया, यह दर्शाता है कि यह जीसी से संबंधित हो सकता है।
एक और संभावना यह हो सकती है कि सिंक्रनाइज़ेशन युक्त कोड जेआईटी संकलित किया गया है और जो आपको मॉनिटर के वास्तविक पते को देखने से रोकता है। हालांकि, मुझे लगता है कि ArrayList.add
पर इसका अनुभव होने के बाद से कम संभावना है। यदि ऐसा है, तो मुझे मॉनिटर के वास्तविक धारक को खोजने का कोई तरीका नहीं है।
क्या आपने [ग्रहण चटाई] (http://www.eclipse.org/mat/) की कोशिश की है? – fhofmann
@fhofmann मुझे ढेर के साथ कोई समस्या नहीं है - यह मेरी मदद कैसे कर सकता है? – bedrin
आप सही हैं। मुझे कुछ समय पहले इसी तरह की समस्या थी और ग्रहण मैट, एक प्रोफाइलर (yourkit) और एक विशिष्ट पार्सर का उपयोग करने के लिए यह पता लगाने के लिए कि समस्या एपीआई कॉन्फ़िगरेशन द्वारा उपयोग की जाने वाली हैशटेबल (गुण) थी। मैट ने मुझे प्रासंगिक कक्षाएं खोजने में मदद की। – fhofmann