2010-11-10 15 views
5

मेरे पास एक पंजीकृत शटडाउन हुक के साथ जावा (1.6) में चल रही एक महत्वपूर्ण प्रक्रिया है। कुछ उदाहरण में जहां मुझे ओओएम मुद्दा मिलता है (इस मुद्दे के बारे में अधिक जानकारी), प्रक्रिया अचानक बंद हो जाती है, मुझे अपने किसी भी लॉग नहीं मिलते हैं, मेरा पकड़ (थ्रोबल एक्स) अपवाद को पकड़ नहीं रहा है।जेवीएम: क्या यह पता लगाना संभव है कि शटडाउन हुक में ओओएम के कारण प्रक्रिया बंद हो रही है?

लेकिन शटडाउन हुक काम करता है। तो अगर यह जानने का कोई तरीका था कि कुछ बुरा ओओएम के कारण प्रक्रिया बंद हो जाएगी, तो मैं बाहर निकलने से पहले आवश्यक जानकारी लॉग कर सकता हूं।

क्या ऐसा करने का कोई तरीका है?

ओओएम: सुनिश्चित नहीं है कि अपवाद क्या है क्योंकि जैसा कि मैंने कहा था कि यह पकड़ा नहीं जाता है। मुझे पता है कि यह ओओएम है क्योंकि मैं प्रक्रिया को

-XX:+HeapDumpOnOutOfMemoryError 

और मुझे एक ढेर डंप फ़ाइल मिलती है। अन्य मामलों में एक अपवाद पकड़ा जाता है, और यह एक ava.lang.OutOfMemoryError: जीसी ओवरहेड सीमा पार हो गई। लेकिन यकीन नहीं है कि यह हमेशा इस मामले में है।

संपादित करें:

मामले में यह स्पष्ट नहीं है: मैं OOM के रूप में यह कुछ परिदृश्य में वैध कारणों से हो सकता रोकने का प्रयास कर नहीं कर रहा हूँ, मैं सिर्फ बनाना चाहते यकीन है कि यह में स्पष्ट है ऐप लॉग फाइल

मेरा प्रश्न है: क्या यह पता लगाना संभव है कि शटडाउन हुक में ओओएम के कारण प्रक्रिया बंद हो रही है?

मुझे यह प्रक्रिया प्रोग्रामिंग और उसी प्रक्रिया से करने की आवश्यकता है।

अब के लिए सबसे अच्छा तरीका यह देखने के लिए है कि क्या यह हालिया तारीख के साथ process_.hprof (मुझे पिड पता है) की एक हीप डंप फ़ाइल java_pid_pid मौजूद है और एक ओओएम था। मुझे लगता है कि मैं Runtime.getRuntime()। FreeMemory() को आजमा सकता हूं और अगर समस्या उपलब्ध हो तो समस्या की रिपोर्ट करें, लेकिन यह सुनिश्चित नहीं है कि यह कितना विश्वसनीय है, शायद जब प्रक्रिया बंद हो रही है तो यह पहले से ही बहुत मेमोरी जारी कर चुका है, उपरोक्त दृष्टिकोण मुझे लगता है कि सबसे अच्छा है।

+0

तो आपका प्रश्न है: "क्या होता है?" - सही? – dacwe

+0

प्रश्न से नाराज न हों, लेकिन क्या आप (अपवाद एक्स) पकड़ते हैं या पकड़ते हैं (थ्रोबल एक्स) ओओएम थ्रोबल है, मुझे यकीन है कि आप जानते हैं और यदि ऐसा होता है तो शायद इसे पकड़ने की संभावना नहीं है, लेकिन फिर भी चेकिंग के लायक ... –

+0

जैसा कि मैंने उल्लेख किया है (शायद यह स्पष्ट नहीं है, मैं फिर से संपादित करूंगा) मेरे पास एक पकड़ (थ्रोबल एक्स) प्रभाव नहीं पड़ रहा है। धन्यवाद – Persimmonium

उत्तर

3

ओओएम मुश्किल हैं क्योंकि यदि JVM स्मृति से बाहर है तो यह एक नए ओओएम को फेंकने के कारण अपवाद हैंडलिंग कोड नहीं चला सकता है।

default uncaught exception handler सेट करने का प्रयास करें। यह सभी बेजोड़ अपवादों को पकड़ लेगा।

+0

होता है यह मेरे लिए नया है। क्या आपके पास संदर्भ हैं? मेरे अनुभव में, ओओएमई एक सामान्य त्रुटि फेंक दी गई है, प्रचारित है और किसी भी त्रुटि की तरह पकड़ लिया गया है। यह निश्चित रूप से हो सकता है कि त्रुटि को संभालने के दौरान, एक और ओओएमई होता है। –

+0

बिल्कुल। मैं पर्याप्त स्पष्ट नहीं था - यह एक नया ओओएम फेंक सकता है और इच्छित कोड को नहीं चला सकता है। मैंने पोस्ट संपादित किया। –

2

आप शायद एक और प्रक्रिया चला सकते हैं जो ओओई के लिए लॉग फ़ाइल की निगरानी करता है (या प्रक्रिया को मारने पर निगरानी करें) और फिर प्रक्रिया को पुनरारंभ करें।

शायद आपके ऐप को यूनिक्स डेमॉन या विंडोज सेवा के रूप में डालना अधिक उपयुक्त होगा।

लेकिन, इसके बजाय प्रोफाइलिंग टूल के साथ मेमोरी लीक की जांच करने के बारे में क्या?

jvisualvm jvisualvm या jconsole की तरह एक अच्छा

1

निगरानी टूल का उपयोग है।

0

आप (तकनीकी रूप से) आउटऑफमेमरी एरर्स को पकड़ सकते हैं, लेकिन यह सुनिश्चित नहीं है कि यदि कोई स्मृति शेष नहीं है, तो आप पकड़ ब्लॉक में कोड निष्पादित करने में सक्षम होंगे।

शायद ओओएम को पकड़ने की कोशिश करने के लायक है (2) कचरा संग्रह (System.gc()) ट्रिगर करें और लॉग या कंसोल करने के लिए कुछ लिखने का प्रयास करें। कोई गारंटी नहीं है लेकिन यह कुछ भी तोड़ नहीं देगा।

+0

जहां तक ​​मैं समझता हूं, System.gc() को ओओएम से पहले स्वचालित रूप से बुलाया जाना चाहिए, समस्या यह है कि जीसी के बाद या उसके दौरान ओओएम अभी भी –

0

आपको इसकी क्षतिपूर्ति करने के बजाय समस्या को हल करना चाहिए।

ढेर डंप आपको ऑब्जेक्ट प्रकार दिखाएगा जो सबसे अधिक स्मृति का उपभोग कर रहे हैं। आपको यह पता लगाने में सक्षम होना चाहिए कि उन वस्तुओं को आवंटित किया गया है, या उन्हें छोड़ दिए जाने के बाद क्यों शेष हैं।

आपको प्राप्त होने वाली विशिष्ट त्रुटि के लिए, इस SO प्रश्न पर एक नज़र डालें: Error java.lang.OutOfMemoryError: GC overhead limit exceeded - ऐसा लगता है कि सबसे आसान समाधान आपके ढेर के आकार को बढ़ाने के लिए होगा।

+0

समस्या यह है कि लॉग ओओएम मुद्दे के बारे में कुछ भी नहीं दिखाते हैं, इसलिए मैं इसे हल करने की कोशिश कर रहा हूं। ओओएम कुछ वैध उपयोग मामलों के रूप में हो सकता है और मुझे इसे लॉग फ़ाइलों में सिग्नल करने की आवश्यकता है। – Persimmonium

+0

@raticulin - नहीं, ओओएम * वैध "उपयोग मामलों में * नहीं हो सकता है। किसी भी ऐप में। यदि आपके पास ऐसे मामलों का उपयोग किया गया है जो उपलब्ध स्मृति की मात्रा से अधिक हो सकते हैं, तो आपको वास्तव में स्मृति से बाहर होने से पहले पहचानना होगा। शायद आपको यह प्राप्त करने के बारे में एक प्रश्न पूछना चाहिए कि ... – Anon

+0

और एक संकेत: सॉफ्ट संदर्भ कोड लिखने का एक तरीका है जो "बहुत अधिक स्मृति की आवश्यकता" स्थिति को सुदृढ़ रूप से संभालता है। – Anon

0

फिर से, जेविसुअलवीएम (जेडीके 6, बिन फ़ोल्डर में) का उपयोग करके अन्य या अन्य प्रोफाइलिंग टूल द्वारा सुझाए गए मुद्दे को हल करने के बजाए इस मुद्दे को हल करने का सबसे अच्छा तरीका है, लेकिन यह मानते हुए कि आप ओओएम कारणों की गंभीर जांच करेंगे, और कोशिश करेंगे उन्हें खत्म करने के लिए, मैं निम्नलिखित पीओसी करने पर विचार करता हूं, (एलोइस उत्तर भी देखें)

जावा प्रक्रिया चलाने के बारे में कैसे ओओएम फेंकने की प्रक्रिया को कॉल करेगा?

आप पकड़ कर सकते हैं जो कुछ भी परिणाम बुलाया प्रक्रिया के उत्पादन में धारा भेजा जा रहा है, और अगर वहाँ एक सुसंगत बाहर निकलें कोड/स्टैक ट्रेस आप ooms

मुझे यकीन है कि वहाँ और अधिक कर रहे हैं रहा हूँ पहचान करने के लिए उपयोग कर सकते हैं को देखने के दृष्टिकोण, लेकिन यह मुझे एक अच्छा, प्रोग्रामेटिक प्रारंभिक बिंदु

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

  • कोई संबंधित समस्या नहीं^_^