JVM ध्वज CMSClassUnloadingEnabled वास्तव में क्या करता है?


183

मैं अपने जीवन के लिए जावा वीएम ध्वज CMSClassUnloadingEnabledवास्तव में क्या करता है, की परिभाषा नहीं पा सकता , कुछ अन्य बहुत ही उच्च-स्तरीय परिभाषाओं के अलावा, जैसे "आपकी पर्मगेन समस्याओं से छुटकारा मिलता है" ( जो यह नहीं करता है , बीडब्ल्यूटी)।

मैंने सन / ओरेकल की साइट पर देखा है, और यहां तक कि विकल्प सूची वास्तव में यह नहीं कहती है कि यह क्या करता है।

झंडे के नाम के आधार पर, मैं अनुमान लगा रहा हूं कि सीएमएस कचरा कलेक्टर डिफ़ॉल्ट अनलोड कक्षाओं द्वारा नहीं करता है, और यह ध्वज इसे चालू करता है - लेकिन मुझे यकीन नहीं हो सकता है।

जवाबों:


219

अपडेट यह उत्तर जावा 5-7 के लिए प्रासंगिक है, जावा 8 में यह तय है: https://blogs.oracle.com/poonam/about-g1-garbage-collector,-permanent-generation-and-metaspace Kudos mt पर जाएं। Uulu

जावा 5-7 के लिए:

दुनिया पर मानक ओरेकल / सन वीएम लुक है: कक्षाएं हमेशा के लिए होती हैं। इसलिए एक बार लोड होने के बाद, वे स्मृति में बने रहते हैं, भले ही किसी को कोई परवाह न हो। यह आमतौर पर कोई समस्या नहीं है क्योंकि आपके पास कई विशुद्ध रूप से "सेटअप" कक्षाएं नहीं हैं (= सेटअप के लिए एक बार उपयोग किया जाता है और फिर फिर कभी नहीं)। यहां तक ​​कि अगर वे 1MB लेते हैं, तो कौन परवाह करता है।

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

यदि आप सक्षम CMSClassUnloadingEnabledकरते हैं तो GC, PermGen को भी स्वीप कर देगा, और उन वर्गों को हटा देगा जिनका अब उपयोग नहीं किया जाता है।

[संपादित करें] आपको सक्षम UseConcMarkSweepGC( सैम हस्लर को धन्यवाद ) भी करना होगा । इस उत्तर को देखें: https://stackoverflow.com/a/3720052/2541


17
के अनुसार stackoverflow.com/a/3720052/2541 के लिए CMSClassUnloadingEnabledकिसी भी प्रभाव पड़ता है, UseConcMarkSweepGCयह भी निर्धारित किया जाना चाहिए
सैम Hasler

1
यह सुनिश्चित नहीं है कि यह UseConcatSweepGC का उपयोग करने के विचार को कैसे प्रभावित करता है, लेकिन ऐसा प्रतीत होता है कि हाल ही में CMSClassUnloadingEnabled में एक बग तय किया गया था। इसे यहाँ तय किया गया है: Bugs.sun.com/bugdatabase/view_bug.do?bug_id=8000325
Bill Rosmus

3
@ केविन: हाँ, निश्चित रूप से। के तल पर देखें groovy.codehaus.org/Running : "। बाद में ग्रूवी गतिशील कक्षाओं बनाता है, लेकिन डिफ़ॉल्ट जावा वी एम PermGen जीसी नहीं है कि आप जावा 6 उपयोग कर रहे हैं या, जोड़ने -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGCUseConcMarkSweepGCसक्षम करने के लिए की जरूरत है CMSClassUnloadingEnabled।"
आरोन दिगुल्ला

1
UseConcMarkSweepGC और CMSClassUnloadingEnabled एक साथ उपयोग करने के बारे में एक अच्छा लेख। blog.redfin.com/devblog/2012/06/…
विक्टर

1
1.8 के लिए अब मान्य नहीं है: blogs.oracle.com/poonam/…
mt.uulu

35

ब्लॉग पोस्ट के अनुसार जावा जेवीएम के लिए -XX विकल्पों की सबसे पूरी सूची , यह निर्धारित करती है कि सीएमएस कचरा कलेक्टर के तहत कक्षा अनलोडिंग सक्षम है या नहीं। डिफ़ॉल्ट है false। एक अन्य विकल्प है जिसे डिफ़ॉल्ट रूप से कहा जाता ClassUnloadingहै trueजो (संभवतः) अन्य कचरा संग्रहकर्ताओं को प्रभावित करता है।

यह विचार यह है कि यदि जीसी यह पता लगाता है कि पहले से लोड किए गए वर्ग का उपयोग अब जेवीएम में कहीं भी नहीं किया गया है, तो यह क्लास बाइटकोड और / या मूल कोड को रखने के लिए उपयोग की गई मेमोरी को पुनः प्राप्त कर सकता है।

यदि आप वर्तमान में CMS संग्राहक का उपयोग कर रहे हैं, तो CMSClassUnloadingEnabled की स्थापना आपकी अनुमति समस्या के साथ मदद कर सकती है । लेकिन संभावना है कि आप सीएमएस का उपयोग नहीं कर रहे हैं, या आपके पास एक वास्तविक क्लास लोडर संबंधित मेमोरी लीक है। बाद के मामले में, आपकी कक्षा कभी भी अप्रयुक्त होने के लिए जीसी को दिखाई नहीं देगी ... और इसलिए कभी भी अनलोड नहीं होगी।


आरोन दिगुल्ला कहते हैं "कक्षाएं हमेशा के लिए हैं"। यह कड़ाई से सच नहीं है, यहां तक ​​कि विशुद्ध रूप से जावा दुनिया में भी। वास्तव में, एक वर्ग का जीवनकाल उसके वर्ग-भार से बंधा होता है। इसलिए यदि आप यह व्यवस्था कर सकते हैं कि एक क्लास-लोडर कचरा एकत्र किया जाता है (और यह हमेशा एक आसान काम नहीं है) तो जिन कक्षाओं में यह लोड होता है, वे भी एकत्र किए जाएंगे।

वास्तव में, यह तब होता है जब आप किसी वेबएप के हॉट रेडेप्लो करते हैं। (या कम से कम, यही होना चाहिए, यदि आप उन समस्याओं से बच सकते हैं जो एक पर्मेन स्टोरेज लीक की ओर ले जाती हैं।)


24

एक उदाहरण जहां यह उपयोगी है:

-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabledहमारे Weblogic 10.3 JVM पर सेट करने से एक समस्या को हल करने में मदद मिली जहां JAX-WS कार्यान्वयन ने प्रत्येक वेब सेवा कॉल के लिए एक नया प्रॉक्सी वर्ग बनाया, जो अंततः मेमोरी त्रुटियों से बाहर निकला।

यह ट्रेस करने के लिए तुच्छ नहीं था। निम्न कोड हमेशा के लिए उसी प्रॉक्सी वर्ग को लौटाता हैport

final MyPortType port = 
Service.create(
        getClass().getResource("/path/to.wsdl"), 
        new QName("http://www.example.com", "MyService"))
    .getPort(
        new QName("http://www.example.com", "MyPortType"), 
        MyPortType.class);

आंतरिक रूप से, यह प्रॉक्सी एक उदाहरण के रूप में दिया गया है weblogic.wsee.jaxws.spi.ClientInstance, जो फिर से एक नए $Proxy[nnnn]वर्ग को सौंप दिया nगया है जहां हर कॉल पर वेतन वृद्धि की गई थी। झंडे जोड़ने पर, nअभी भी वृद्धि हुई थी, लेकिन कम से कम उन अस्थायी वर्गों को स्मृति से हटा दिया गया था।

अधिक सामान्य नोट पर, जावा प्रतिबिंब और समीपस्थ के माध्यम से भारी उपयोग करते समय यह बहुत उपयोगी हो सकता है java.lang.reflect.Proxy


वास्तविक अनुभव साझा करने के लिए +1। हमें टॉर्बॉक्स पर भी यह समस्या थी जहां सर्वर ने JRuby संकलन प्रक्रियाओं के कारण बड़ी संख्या में कक्षाएं बनाईं।
nurettin

7
यह भी ध्यान दें कि-XX:+CMSPermGenSweepingEnabled-XX:+CMSClassUnloadingEnabled
nurettin

3
इस समस्या के लिए एक वास्तविक सुधार हालांकि पोर्ट को एक बार बनाना और इसे फिर से उपयोग करना है। इस तरह से JAX-WS का उपयोग किया जाना चाहिए। पोर्ट 100% थ्रेड सुरक्षित भी है।
रस्टीक्स

@rustyx: क्या आप कुछ आधिकारिक लिंक के साथ दावा कर सकते हैं? मैं हमेशा वेब सेवाओं के परदे के पीछे और स्टब्स का उपयोग करने से बहुत सावधान रहा हूं ... उदाहरण के लिए अपाचे सीएक्सएफ अस्वीकरण देखें । या यह सवाल
लुकास ईडर

1
@rukavitsya: जैसा कि मैंने अपने जवाब में कहा है। हर बार जब मैंने उपरोक्त तर्क को कॉल किया, तो एक नया प्रॉक्सी बनाया गया था
लुकास ईडर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.