2009-07-18 23 views
8

मेरे पास कोड का एक टुकड़ा है जो स्मृति में एक बहुत बड़ी छवि लोड करता है। तो यह छवि को लोड करने से पहलेकब कचरा संग्रहण

System.gc(); 

पर कॉल करने के लिए उचित बात की तरह लग रहा था। मैं जो कह सकता हूं उससे कोई समस्या नहीं है।

कल मैंने FindBugs नामक सॉफ़्टवेयर का एक बहुत ही उपयोगी टुकड़ा उपयोग करने का निर्णय लिया जो आपके कोड को स्कैन करता है और उन समस्याओं को रिपोर्ट करता है जो बग या आम तौर पर सलाह नहीं दे सकते हैं। समस्या यह है कि मेरे द्वारा वर्णित कोड का यह टुकड़ा रिपोर्ट हो जाता है। विवरण यह है:

... कचरा संग्रह को मजबूर करता है; बेंच मार्किंग कोड

में छोड़कर अत्यंत संदिग्ध और यह विस्तृत करने पर चला जाता है:

कोड स्पष्ट रूप से कचरा संग्रह invokes। बेंचमार्किंग में विशिष्ट उपयोग के अलावा, यह बहुत संदिग्ध है।

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

तो मेरे सवाल है: यह नहीं ठीक प्रोग्राम के रूप में इस तरह के एक मामले में कचरा कलेक्टर कॉल करने के लिए है? मेरा कोड केवल इसे एक बार कॉल करता है और जिस विधि में यह है, वह शायद ही कभी उपयोग किया जाता है। और यदि इसे कॉल करना ठीक नहीं है तो आपको एक ऐसे मामले में क्या करना चाहिए जहां आपको बहुत मेमोरी गहन ऑपरेशन करने से पहले जितनी मेमोरी चाहिए उतनी मेमोरी चाहिए और आपको इससे पहले जितनी मेमोरी उतनी ही खाली होनी चाहिए?

+1

इस मामले में आप शायद प्रदर्शन को क्रमबद्ध कर रहे हैं। यदि आप जीसी को कब चलाना तय करते हैं, तो यह ठीक से चल सकता है जब एप्लिकेशन I/O पर अवरुद्ध हो रहा है। –

+0

प्रश्न: System.gc() को कब कॉल करें। ए: कभी भी – KitsuneYMG

+1

वाह जो अंतर्दृष्टि भरा था। मैं पूरी तरह से समझता हूं कि मुझे आपके जवाब से जीसी क्यों नहीं कहना चाहिए। आपका बहुत बहुत धन्यवाद। –

उत्तर

9

क्या आपको System.gc() के साथ कोई प्रदर्शन सुधार मिला है? मुझे ऐसा नहीं लगता है, क्योंकि आपके पास छवियों को लोड करने से पहले बहुत सारी ऑब्जेक्ट्स नहीं एकत्र की जानी चाहिए।

आमतौर पर आधुनिक कचरा कलेक्टरों को चलाने के लिए सबसे अच्छा पता है, इसलिए आपको एक संग्रह को मजबूर नहीं करना चाहिए, जब तक कि आपके पास वास्तव में वास्तव में कोई अच्छा कारण न हो। (उदाहरण के लिए उस प्लगइन द्वारा सुझाए गए बेंचमार्किंग एप्लिकेशन)

बीटीडब्ल्यू: कॉलिंग System.gc() कॉलिंग को "पूर्ण" या "बड़ा" संग्रह करने के लिए वीएम की सिफारिश करता है, जिसका अर्थ है कि सभी थ्रेड जल्द ही बंद हो जाते हैं। अन्यथा यह शायद केवल "छोटे" कचरा संग्रह करेगा, जो सभी धागे को नहीं रोकता है।

अपने कार्यक्रम को -verbose के साथ चलाएं: जीसी यह देखने के लिए कि कितने बाइट एकत्र किए जाते हैं। http://java.sun.com/developer/technicalArticles/Programming/GCPortal/

+4

System.gc() कुछ भी "बल" नहीं करता है। वीएम इसे अनदेखा करने के लिए स्वतंत्र है। जावाडोक में शब्द "जीसी विधि को बुला रहा है * सुझाव देता है * जावा वर्चुअल मशीन अप्रयुक्त वस्तुओं को रीसाइक्लिंग करने के लिए प्रयास खर्च करती है" (जोर मेरा) –

+2

-1 सिस्टम.gc() पर जावाडोक पढ़ने के लिए विफल होने के लिए एड्रियन ने कहा, यह बल कुछ भी तो नहीं। http://stackoverflow.com/questions/1147511/how-can-i-estimate-amount-of-memory-left-with-calling-system-gc/1149182#1149182 वास्तविक फोर्सिंग जीसी के लिए – KitsuneYMG

1

कचरा कलेक्टर को कॉल करना ठीक है, आपको इससे कोई "समस्याएं" नहीं मिलती हैं। हालांकि, मुझे संदेह है कि यह महत्वपूर्ण रूप से प्रदर्शन को बढ़ावा देगा, जब तक कि यह कॉल आवंटित डेटा को डिफ्रैग करने से भी संबंधित न हो। मुझे यह नहीं पता।

इस मामले में आपको क्या करना चाहिए कोड कोड है। इसे कई बार चलाएं, देखें कि आपको किस प्रकार के परिणाम मिलते हैं।

9

आमतौर पर जीसी आपके से चालाक है, इसलिए जब भी रनटाइम निर्णय लेता है तो इसे चलाने देना बेहतर होता है। यदि रनटाइम को स्मृति की आवश्यकता है, तो यह जीसी स्वयं

+1

समस्या यह है कि यह केवल कुछ आवंटित करने का प्रयास करने के बाद ही है। यदि आप ऐसी स्थिति में हैं जहां आप "जानते हैं" कि आपके पास बहुत ही असंगठित मेमोरी लेआउट है और आप "जानते हैं" हैं तो आपको स्मृति के बड़े ब्लॉक की आवश्यकता होगी, आप पहले जीसी को कुछ निर्देशों का आह्वान कर सकते हैं। –

+2

आप यह सुनिश्चित करने के लिए कभी भी "नहीं जानते" कि आपके पास असंगठित मेमोरी लेआउट है। जीसी सिर्फ इतना ही चल सकता था, जो आप जानते हैं। मार्क-एंड-स्वीप का "चिह्न" भाग संसाधन और समय लेता है भले ही आप कुछ भी एकत्र न करें।यही कारण है कि यह जीसी की कोशिश करने और बाहर करने के लिए लगभग हमेशा एक नकारात्मक नकारात्मक या (सबसे अच्छा मामला) तोड़ने का मामला है। – Jason

+0

रनटाइम और जीसी बदलने के लिए स्वतंत्र है और जब भी ऐसा लगता है स्मृति में ऑब्जेक्ट्स के चारों ओर स्थानांतरित होता है (यदि आप सी दुनिया से आते हैं तो ऑब्जेक्ट पॉइंटर के पॉइंटर की तरह अधिक होते हैं), तो आप शायद ही कभी "जान लें" एक असंगठित लेआउट। – nos

1

चलाएगा आमतौर पर, आपको कचरा कलेक्टर में हस्तक्षेप नहीं करना चाहिए। यदि छवि लोड करने से पहले कुछ स्मृति मुक्त करना आवश्यक है, तो कचरा कलेक्टर आपके लिए यह करेगा।

भले ही, यदि आप केवल एक बार ऐसा कर रहे हैं, तो शायद यह आपके प्रदर्शन को काफी प्रभावित नहीं करेगा। लूप में किए गए चीजें कहीं अधिक महत्वपूर्ण हैं।

1

आप पहले से ही अच्छी सलाह है, जो मैं दोहराना के लिए नहीं की कोशिश करेंगे के बहुत सारे मिल गया:

वहाँ भी कचरा संग्रहण यहां पर तकनीकी जानकारी के बहुत सारे है।

यदि आपको वास्तव में जीसी के साथ समस्याएं मिलती हैं, जैसे कि दूसरे के लिए आपके आवेदन की पूर्ण स्टॉप की तरह, निम्न कार्य करें: 1. जांचें कि System.gc() पर कोई कॉल नहीं है; 2. जीसी को कॉन्फ़िगर करने के लिए विभिन्न विकल्पों की जांच करें। आसपास के बहुत सारे हैं, और वे बहुत अधिक सहायक हैं, फिर जीसी मजबूर कर रहे हैं।

1

सुनिश्चित करें कि बड़ी वस्तुओं को जितनी जल्दी हो सके gc'ed किया जा सकता है। अर्थात। शून्य को चर सेट करें और/या उन्हें दायरे से बाहर निकलने दें। इससे मदद मिलती है!

0

आम तौर पर, नहीं। System.gc() को कॉल करना उचित नहीं है। हालांकि, मेरे पास कुछ ऐसे मामले हैं जहां यह समझ में आया।

मेरे द्वारा लिखे गए सॉफ़्टवेयर में, एक अंतर्निहित प्रदर्शन ट्रैकिंग परत है। यह ज्यादातर स्वचालित परीक्षण के दौरान प्रयोग किया जाता है, लेकिन क्षेत्र में निदान उद्देश्यों के लिए उपयोग किया जा सकता है। परीक्षणों के बीच या विशिष्ट रनों के बाद हम System.gc को कुछ बार कॉल करेंगे और फिर स्मृति को अभी भी रिकॉर्ड करेंगे। यह समय के साथ मेमोरी खपत प्रवृत्ति लाइनों को देखने के लिए हमें एक बुनियादी मेमोरी पैर प्रिंट बेंचमार्क प्रदान करता है। हालांकि यह बाहरी जेवीएम इंटरफेस के साथ किया जा सकता है, इसे जगह में करना आसान था और सटीक संख्याओं की आवश्यकता नहीं थी।

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

1

यदि स्मृति आवंटन विफल रहता है, तो एक जीसी चक्र शुरू किया जाता है और आवंटन फिर से प्रयास किया जाता है।

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