2011-11-11 14 views
5

में ऑब्जेक्ट्स एकत्र करने के लिए अंतिमकर्ता थ्रेड की प्राथमिकता कैसे बढ़ा सकता हूं मैंने मेमोरी रिसाव जानने के लिए प्रोफाइलर के साथ अपने जावा एप्लिकेशन की निगरानी की है। और मैं वर्ग जो स्मृति जोमैं जीसी

java.lang.ref.Finalizer 

है की लगभग 80% ले जा मिला तो मैं ऊपर वर्ग के लिए यह गूगल और महान लेख पाया http://www.fasterj.com/articles/finalizer1.shtml

अब किसी भी एक मुझे सुझाव दे सकते हैं कि कैसे मैं करने के लिए FinalizerThread की प्राथमिकता बढ़ा सकते हैं जीसी में उन वस्तुओं को इकट्ठा करें।

एक और बात मैं कर्नेल संस्करण के साथ लिनक्स पर इस मुद्दे का सामना करना पड़ रहा लिनक्स 2.6.9-5.ELsmp (i386) और लिनक्स 2.6.18-194.17.4.el5 (i386) लेकिन यह ठीक काम कर रहा है (ओओएम त्रुटि के बिना) लिनक्स 2.6.18-128.el5PAE (i386) पर।

क्या यह समस्या लिनक्स कर्नेल की वजह से है? क्या FinalizerTread की प्राथमिकता में सुधार करने के लिए कोई JVM चर है?

अग्रिम में Thanx।

+1

अच्छा सवाल, मुझे लगता है कि आपको सामान्य रूप से अंतिम रूपकों के उपयोग को कम करने की आवश्यकता है। –

+0

शायद पीएई मोड में आपके पास बस अधिक मेमोरी उपलब्ध है (गैर-पीएई 4 जीबी तक सीमित है) - 'फ्री' की जांच करें। मुझे नहीं लगता कि कर्नेल संस्करण यहां खेल रहा है। –

+0

धन्यवाद दान, जैसा कि पीटर नीचे सुझाव देता है, अब मैं फाइल सिस्टम के साथ जांच कर रहा हूं। – user1041580

उत्तर

2

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

for(Thread t: Thread.getAllStackTraces().keySet()) 
    if (t.getName().equals("Finalizer")) { 
     System.out.println(t); 
     t.setPriority(Thread.MAX_PRIORITY); 
     System.out.println(t); 
    } 

प्रिंट

Thread[Finalizer,8,system] 
Thread[Finalizer,10,system] 

जब तक आप अपने सभी कोर के 100% का उपयोग कर रहे हैं, या इसे बंद करने, प्राथमिकता कोई फर्क नहीं पड़ता क्योंकि भले सबसे कम प्राथमिकता के रूप में ज्यादा सीपीयू मिल जाएगा जैसा कि यह चाहता है

नोट: लिनक्स पर, जब तक आप जड़ नहीं हैं तब तक उठाए गए प्राथमिकताओं को अनदेखा कर दिया जाएगा।

इसके बजाय आपको अंतिम कार्यकर्ता जो काम कर रहा है उसे कम करना चाहिए। आदर्श रूप में इसे करने के लिए कुछ भी नहीं होना चाहिए। फाइनेंजर में उच्च भार का एक कारण संसाधन बना रहा है जिसे बंद किया जाना चाहिए लेकिन इसे छोड़ दिया जा रहा है। (इसके बजाय संसाधन को बंद करने के लिए फाइनलाइज़र को छोड़कर)

संक्षेप में, आपको यह निर्धारित करना चाहिए कि कौन से संसाधनों को अंतिम रूप दिया जा रहा है और यह सुनिश्चित कर लें कि उन्हें अंतिम रूप देने() कहने पर कुछ भी करने की आवश्यकता नहीं है, आदर्श रूप से उपयोग नहीं करते यह विधि बिल्कुल

यह संभव है कि लिनक्स कर्नेल के पुराने संस्करण को बंद करने के लिए संसाधनों को थोड़ा अधिक समय लगेगा। मैं जांचता हूं कि हार्डवेयर समान है क्योंकि इसका मतलब यह हो सकता है कि संसाधन को साफ करने में अधिक समय लगता है। (लेकिन वास्तविक फिक्स यह सुनिश्चित करना है कि इसे करने की आवश्यकता नहीं है)

+0

जावा जावा अंतर कर सकता है। क्योंकि पहले दो लिनक्स (जहां ओओएम मुद्दा उठता है), 64 बिट जावा का उपयोग कर रहा हूं और एक जहां यह ठीक काम कर रहा है, 32 बिट का उपयोग कर रहा हूं? – user1041580

+0

जावा संस्करण, चाहे आप 64 बिट या 32 बिट का उपयोग कर रहे हों, आप कौन सी हार्डवेयर सीपीयू, मेमोरी, डिस्क, नेटवर्क बैंडविड्थ, वर्कलोड, उदाहरण के लिए उपयोग कर रहे हैं क्या यह अलग-अलग काम कर रहा है, संसाधनों को बंद करने में कितना व्यस्त है उदा। यदि वे किसी डेटाबेस या सेवा से कनेक्ट होते हैं तो सभी इस मामले में एक अंतर डालते हैं। कर्नेल संस्करण एक फर्क पड़ सकता है लेकिन मैं पहले पहली सूची की जांच करता हूं। –

+0

यदि आपके पास जावा का पुराना संस्करण है, तो 64-बिट संस्करण 32-बिट संस्करण की तुलना में अधिक मेमोरी का उपयोग कर सकता है। यदि आपके पास नवीनतम संस्करण है तो अंतर बहुत छोटा है (क्योंकि यह '-XX: + UseCompressedOops' का उपयोग करता है) वास्तविक फिक्स कोड को ठीक करना है, JVM के साथ टिंकर नहीं। –

2

फाइनलजर थ्रेड शायद ही कभी अधिक काम कर रहा है। संसाधनों को पहले से ही जारी किया जाना चाहिए था। सुनिश्चित करें कि आपका कोड मानक तरीके से संसाधनों को संभाला जा रहा है।

जावा SE 7:

try (final Resource resource = acquire()) { 
    use(resource); 
} 

पूर्व जावा SE 7:

final Resource resource = acquire(); 
try { 
    use(resource); 
} finally { 
    resource.release(); 
} 
0

टॉम Hawtin बताते हैं के रूप में, आप एक finalize() विधि है कि Thread.currentThread() कॉल बनाने के द्वारा FinalizerThread की पकड़ प्राप्त कर सकते हैं और फिर इसे एक स्थिर में धक्का देता है। आप शायद इसकी प्राथमिकता भी बदल सकते हैं।

लेकिन एक अच्छा मौका है कि यह कोई अच्छा काम नहीं करेगा। केवल एक फाइनेंजर थ्रेड होने की संभावना है। और समस्या है कि या तो होने की संभावना है:

  • धागा बहुत ज्यादा काम है, क्योंकि बस नहीं रख सकते हैं किया जाना है, या
  • धागा कुछ द्वारा अवरुद्ध किया जा रहा है आप finalizer में क्या कर रहे हैं तरीकों।

(और, मैं उम्मीद थी को finalizer धागा पहले से ही उच्च प्राथमिकता के रूप में चिह्नित किया जा।)

लेकिन किसी भी तरह, मुझे लगता है कि एक बेहतर समाधान finalize() तरीकों में से छुटकारा पाने के लिए है। मैं शर्त लगाता हूं कि वे ऐसा कुछ कर रहे हैं जो या तो अनावश्यक है ... या डोडी। विशेष रूप से, गिराए गए वस्तुओं से संसाधनों को पुनः प्राप्त करने के लिए अंतिमकर्ताओं का उपयोग करना उस विशेष समस्या को हल करने का एक खराब तरीका है। (टॉम Hawtin के जवाब देखें।)

+0

फाइनलजर थ्रेड ऑब्जेक्ट को पकड़ें? आसान। एक स्थिरकर्ता के साथ एक ऑब्जेक्ट बनाएं जो स्थिर में 'Thread.currentThread()' को दबाए। –

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