2011-02-10 14 views
37

मैं इस समय जावा एप्लिकेशन पर काम कर रहा हूं और इसके मेमोरी उपयोग को अनुकूलित करने के लिए काम कर रहा हूं। जहां तक ​​मुझे पता है, मैं उचित कचरा संग्रह के लिए दिशानिर्देशों का पालन कर रहा हूं। हालांकि, ऐसा लगता है कि मेरा ढेर अपने अधिकतम आकार में बैठता प्रतीत होता है, भले ही इसकी आवश्यकता नहीं है।क्या उपयोग में नहीं होने पर जावा ढेर को कम करने का कोई तरीका है?

मेरा प्रोग्राम एक घंटे में संसाधन संसाधन गहन कार्य चलाता है, जब कंप्यूटर किसी व्यक्ति द्वारा उपयोग में नहीं होता है। यह कार्य स्मृति के एक सभ्य हिस्से का उपयोग करता है, लेकिन फिर कार्य पूर्ण होने के तुरंत बाद इसे मुक्त करता है। NetBeans प्रोफाइलर पता चलता है कि स्मृति के उपयोग इस तरह दिखता है:

Java program memory usage

मैं वास्तव में जब उपयोग में नहीं ओएस के लिए वापस कि ढेर अंतरिक्ष के सभी देना चाहते हैं। मेरे लिए यह सब कुछ हॉग करने का कोई कारण नहीं है जबकि कार्यक्रम कम से कम एक घंटे तक कुछ भी नहीं कर रहा है।

क्या यह संभव है? धन्यवाद।

+0

मैं यह है कि क्या JVM आप उपयोग कर रहे पर निर्भर करता है लगता है। जेवीएम स्पेक इस बारे में कुछ भी नहीं कहता है, आईआईआरसी। – templatetypedef

+0

क्या इसका मतलब यह है कि इसे आवंटित करने के बाद यह एप्लिकेशन के जीवन चक्र के लिए है? – jocull

+0

कृपया जेवीएम उद्धृत करें जो ओएस को मेमोरी देता है। मैं एक के बारे में नहीं जानता। – duffymo

उत्तर

26

आप शायद -XX:MaxHeapFreeRatio के साथ खेल सकते हैं - यह जीसी को कम करने से पहले यह ढेर का अधिकतम प्रतिशत (डिफ़ॉल्ट 70) है। शायद इसे थोड़ा कम (40 या 50?) सेट करना और फिर System.gc() का उपयोग करके आप वांछित व्यवहार प्राप्त करने के लिए कुछ लंबाई ले सकते हैं?

ऐसा करने के लिए मजबूर करने का कोई तरीका नहीं है, लेकिन आप ऐसा करने के लिए JVM को आजमा सकते हैं और प्रोत्साहित कर सकते हैं लेकिन जब आप चाहें तो स्मृति को यंक नहीं कर सकते। और जब उपरोक्त ढेर को कम कर सकता है, तो उस स्मृति को सीधे ओएस पर वापस नहीं दिया जाएगा (हालांकि यह JVM के हालिया कार्यान्वयन में करता है।)

+0

यह दिलचस्प है, लेकिन यह सवाल स्वयं को संबोधित नहीं करता है, "मैं वास्तव में उस ढेर की जगह को ओएस पर वापस देना चाहता हूं जब उपयोग में नहीं है ... क्या यह संभव है?" ... जीसी दिशानिर्देश बस जेवीएम को बताएं कि कैसे (एकात्मक रूप से बढ़ रहा है) जावा ढेर का प्रबंधन करें। – andersoj

+7

@andersoj: यह सेटिंग _does_ ओएस को रैम वापस दे देती है। एक प्रभावशाली उदाहरण के लिए http://stopcoding.wordpress.com/2010/04/12/more-on-the-incredible-shrinking-jvm-heap देखें। –

+0

@ एएच .: बहुत अच्छा, बहुत अच्छा। मैं अनजान था, सूचक के लिए धन्यवाद। (इच्छा है कि मैं इसे कवर करने के लिए ऊपर दिए गए मेरे उत्तर को बेहतर बनाने के लिए पर्याप्त समझदार था ... यदि आप यहां एक उत्तर पोस्ट करते हैं तो मैं ऊपर जाऊंगा।) – andersoj

3

जेवीएम इस तरह से काम नहीं करता है। आप इसे ओएस पर वापस नहीं दे सकते।

जैसा कि चार साल पहले लिखा गया था, कई लोगों द्वारा नोट किया गया है, यदि आप जेवीएम को उचित जीसी सेटिंग्स देते हैं तो आप ओएस को मेमोरी दे सकते हैं।

+1

मुझे लगता है कि यह कटाक्ष और सच्चाई का मिश्रण है? मैंने देखा है कि अगर मैंने प्रोफाइलर पर कचरा इकट्ठा बटन लगभग 50 बार मारा है तो मैं ढेर को उचित स्तर पर वापस ले सकता हूं। – jocull

+2

(जावा) ढेर को निम्न स्तर तक ले जाना स्मृति को ओएस को वापस नहीं देता है। प्रभाव वही है, हालांकि, अप्रयुक्त पृष्ठों को बदल दिया गया है और इसका कोई महत्वपूर्ण प्रभाव नहीं है। – andersoj

+1

नहीं, सच। कटाक्ष की औंस नहीं। जहां तक ​​मुझे पता है, ढेर का आकार घट सकता है, लेकिन जेवीएम के लिए अलग स्मृति सेट ओएस पर वापस नहीं जाती है। – duffymo

3

एक संभावना है कि आपकी पृष्ठभूमि जावा एप्लिकेशन एक बाहरी लॉन्च करे अपने काम को चलाने के लिए प्रत्येक घंटे जेवीएम उदाहरण। इस तरह केवल आपके मूल जेवीएम अनुप्रयोग कार्यों के बीच चल रहा है।

+0

यह एक अच्छा विचार है, धन्यवाद। – jocull

2

यदि आपका ऐप निष्क्रियता की अवधि के दौरान quiescent है, तो यह संभव है कि ओएस आपके लिए उन पृष्ठों को स्वैप कर देगा, भौतिक स्मृति पर उनके दबाव को कम करेगा।

http://www.linuxvox.com/2009/10/what-is-the-linux-kernel-parameter-vm-swappiness/

3

जावा सबसे अच्छा गुप्त रखा: -Xincgc यह प्रभाव प्रदर्शन करता है लेकिन ऐसा नहीं है कि ज्यादा हमेशा। कभी-कभी ऐसा होता है, जो आप कर रहे हैं उस पर निर्भर करता है। वृद्धिशील कचरा कलेक्टर हाथ मेमोरी सिस्टम को वापस अच्छी तरह से वापस!

+0

धन्यवाद! अगर मैं इस परियोजना पर वापस जाने का मौका देता हूं तो मैं उस पर ध्यान रखूंगा। – jocull

+2

नोट: ओपनजेडीके 8 का उपयोग करके, यह प्रिंट करता है 'ओपनजेडीके 64-बिट सर्वर वीएम चेतावनी: वृद्धिशील सीएमएस का उपयोग बहिष्कृत किया गया है और भविष्य में रिलीज में हटा दिया जाएगा' –

6

लघु संस्करण: हाँ आप कर सकते हैं।

लांग संस्करण:

कैसे जावा/JVM स्मृति का प्रबंधन करता है

सबसे अनुप्रयोगों JVM चूक ठीक हैं। ऐसा लगता है कि जेवीएम अपेक्षा करता है कि एप्लिकेशन केवल सीमित अवधि तक चलें। इसलिए यह अपने आप पर मुफ्त स्मृति प्रतीत नहीं होता है।

क्रम तय करने के लिए कैसे और कब कचरा संग्रहण प्रदर्शन करने के लिए JVM मदद करने के लिए, निम्नलिखित मानकों आपूर्ति की जानी चाहिए:

  • -Xms न्यूनतम ढेर आकार
  • –Xmx निर्दिष्ट करता है अधिक से अधिक ढेर आकार निर्दिष्ट करता

सर्वर अनुप्रयोगों के लिए जोड़ें: -server

गु मेरे लिए पर्याप्त नहीं है। मुझे और नियंत्रण चाहिए!

यदि ऊपर उल्लिखित पैरामीटर पर्याप्त नहीं हैं, तो आप कचरा संग्रह के संबंध में JVM के व्यवहार को प्रभावित कर सकते हैं।

सबसे पहले आप वीएम को बताने के लिए System.gc() का उपयोग कर सकते हैं जब आपको लगता है कि कचरा संग्रह समझ में आता है। और दूसरा आप निर्दिष्ट कर सकते हैं जो कचरा लेनेवालों की JVM उपयोग करना चाहिए:

कचरा कलेक्टरों के विभिन्न प्रकार:

  • सीरियल जीसी

    कमांड लाइन पैरामीटर: -XX:+UseSerialGC

    बंद हो जाता है आपका आवेदन और जीसी करता है।

  • समानांतर जीसी

    कमांड लाइन पैरामीटर: -XX:+UseParallelGC -XX:ParallelGCThreads=value

    रन नाबालिग संग्रह अपने आवेदन के साथ समानांतर मेंप्रमुख संग्रह के लिए आवश्यक समय कम करता है, लेकिन अन्य धागे का उपयोग करता है।

  • समानांतर को संक्षिप्त करने जीसी

    कमांड लाइन पैरामीटर: -XX:+UseParallelOldGC

    रन प्रमुख संग्रह अपने आवेदन के साथ समानांतर में। अधिक CPU संसाधनों का उपयोग करता है, स्मृति उपयोग को कम करता है।

  • सीएमएस जीसी

    कमांड लाइन पैरामीटर: -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=value -XX:+UseCMSInitiatingOccupancyOnly

    छोटे संग्रह करता है, और अधिक बार सीरियल जीसी, इस प्रकार आवेदन के टूट जाता है/बंद हो जाता है सीमित।

  • G1

    कमांड लाइन पैरामीटर: -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC

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

    उदाहरण

मेमोरी उपयोग: Play Framework WebApp without optimizations आप देख सकते हैं, यह काफी ढेर अंतरिक्ष के एक बहुत का उपयोग करता है, और उपयोग अंतरिक्ष नियमित रूप से मुक्त हो जाता है।

इस मामले में पैरामीटर के साथ अनुकूलन केवल प्रभावी नहीं थे। कुछ निर्धारित कार्य थे जो बहुत मेमोरी का इस्तेमाल करते थे। इस मामले में मेमोरी गहन परिचालन के बाद System.gc() के साथ संयुक्त CMS GC का उपयोग कर सर्वोत्तम प्रदर्शन प्राप्त किया गया था। नतीजतन वेब ऐप का मेमोरी उपयोग 1.8 जीबी से घटकर 400-500 एमबी हो गया।

Memory is being freed by the JVM and returned to the OS नोट:: मैं "जीसी प्रदर्शन करना" के लिए VisualVM के बटन का इस्तेमाल किया

आप यहाँ VisualVM जो दिखाता है कि स्मृति JVM द्वारा मुक्त हो जाता है और वास्तव में ओएस के लिए वापस आ से दूसरे स्क्रीनशॉट देख सकते हैं मेरे कोड में System.gc() के बजाय जीसी निष्पादित करें, क्योंकि निर्धारित कार्य जो स्मृति का उपभोग करते हैं केवल विशिष्ट समय पर लॉन्च किए जाते हैं और VisualVM के साथ कैप्चर करने में कुछ कठिन होता है।

अतिरिक्त पठन

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

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