यह सरल नमूना कोड समस्या का प्रदर्शन करता है। मैं ArrayBlockingQueue
बना रहा हूं, और एक धागा जो take()
का उपयोग करके इस कतार पर डेटा की प्रतीक्षा करता है। लूप खत्म हो जाने के बाद, सिद्धांत में दोनों कतार और धागे कचरे को एकत्रित किया जा सकता है, लेकिन व्यवहार में मुझे जल्द ही OutOfMemoryError
मिलता है। जीसीएड होने के लिए इसे क्या रोक रहा है, और यह कैसे तय किया जा सकता है?OutOfMemoryError - प्रतीक्षा प्रतीक्षा थ्रेड कचरा क्यों नहीं हो सकता है?
/**
* Produces out of memory exception because the thread cannot be garbage
* collected.
*/
@Test
public void checkLeak() {
int count = 0;
while (true) {
// just a simple demo, not useful code.
final ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<Integer>(2);
final Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
abq.take();
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
// perform a GC once in a while
if (++count % 1000 == 0) {
System.out.println("gc");
// this should remove all the previously created queues and threads
// but it does not
System.gc();
}
}
}
मैं जावा 1.6.0 का उपयोग कर रहा हूं।
अद्यतन: कुछ पुनरावृत्तियों के बाद जीसी प्रदर्शन करें, लेकिन इससे मदद नहीं मिलती है।
मुझे यह समस्या नहीं है, जब भी मैं प्रत्येक लूप में System.gc() चलाता हूं तो धागे नष्ट नहीं होते हैं। – martinus
@ मार्टिनस अधिक सावधानी से पढ़ें। धागे को इकट्ठा करने में कितना समय लगता है धागे को इकट्ठा करने के लिए जितना समय लगता है उतना लंबा होता है। यदि आप एक अस्थिर बाथटब भरना शुरू करते हैं और आप टब नालियों की तुलना में तेज़ी से पानी जोड़ते हैं, तो टब अंततः भर जाएगा और बह जाएगा। यह एक संसाधन आवंटन/deallocation दौड़ की स्थिति है। क्या होता है यदि आप केवल 100 धागे बनाते हैं, और थोड़ी देर में जारी रहते हैं? क्या धागे अंततः एकत्र हो जाते हैं? – Wedge
@ वेज, नहीं, वे कभी एकत्र नहीं हुए! या कुछ और करो। यहां तक कि जब मैं प्रत्येक लूप के अंत में एक सेकंड प्रतीक्षा करता हूं तब भी कभी भी जीसीडी नहीं होता है। – martinus