जावा वर्चुअल मशीन - जेनेशनल जीसी

अधिकांश JVM तीन पीढ़ियों में ढेर को विभाजित करते हैं - the young generation (YG), the old generation (OG) and permanent generation (also called tenured generation)। ऐसी सोच के पीछे क्या कारण हैं?

अनुभवजन्य अध्ययनों से पता चला है कि बनाए गए अधिकांश वस्तुओं में बहुत कम जीवनकाल होता है -

स्रोत

https://www.oracle.com

जैसा कि आप देख सकते हैं कि समय के साथ अधिक से अधिक वस्तुओं को आवंटित किया जाता है, बाइट्स जीवित रहने की संख्या कम (सामान्य रूप से) हो जाती है। जावा वस्तुओं में मृत्यु दर अधिक है।

हम एक साधारण उदाहरण में देखेंगे। जावा में स्ट्रिंग क्लास अपरिवर्तनीय है। इसका मतलब यह है कि हर बार आपको एक स्ट्रिंग ऑब्जेक्ट की सामग्री को बदलने की आवश्यकता होती है, आपको पूरी तरह से एक नई ऑब्जेक्ट बनाना होगा। मान लें कि आप लूप में 1000 बार स्ट्रिंग में बदलाव करते हैं जैसा कि नीचे दिए गए कोड में दिखाया गया है -

String str = “G11 GC”;

for(int i = 0 ; i < 1000; i++) {
   str = str + String.valueOf(i);
}

प्रत्येक लूप में, हम एक नया स्ट्रिंग ऑब्जेक्ट बनाते हैं, और पिछले पुनरावृत्ति के दौरान बनाई गई स्ट्रिंग बेकार हो जाती है (अर्थात, यह किसी भी संदर्भ से संदर्भित नहीं है)। उस वस्तु का टी जीवनकाल सिर्फ एक पुनरावृत्ति था - वे कुछ ही समय में जीसी द्वारा एकत्र किए जाएंगे। इस तरह की अल्पकालिक वस्तुओं को ढेर के युवा पीढ़ी के क्षेत्र में रखा जाता है। युवा पीढ़ी से वस्तुओं को इकट्ठा करने की प्रक्रिया को मामूली कचरा संग्रह कहा जाता है, और यह हमेशा 'stopthe-world' ठहराव का कारण बनता है।

जैसे ही युवा पीढ़ी भर जाती है, जीसी एक मामूली कचरा संग्रह करता है। मृत वस्तुओं को छोड़ दिया जाता है, और जीवित वस्तुओं को पुरानी पीढ़ी में ले जाया जाता है। इस प्रक्रिया के दौरान एप्लिकेशन थ्रेड बंद हो जाते हैं।

यहां, हम उन लाभों को देख सकते हैं जो इस तरह की पीढ़ी के डिजाइन प्रदान करते हैं। युवा पीढ़ी ढेर का एक छोटा सा हिस्सा है और जल्दी से भर जाती है। लेकिन इसे संसाधित करने में पूरे ढेर को संसाधित करने में लगने वाले समय की तुलना में बहुत कम समय लगता है। इसलिए, 'स्टॉप-द -वर्ल्ड' इस मामले में बहुत कम है, हालांकि अधिक लगातार। हमें हमेशा छोटे लोगों के लिए अधिक समय के लिए लक्ष्य रखना चाहिए, भले ही वे अधिक लगातार हो सकते हैं। हम इस ट्यूटोरियल के बाद के अनुभागों पर विस्तार से चर्चा करेंगे।

युवा पीढ़ी को दो स्थानों में विभाजित किया गया है - eden and survivor space। एडेन के संग्रह के दौरान बची हुई वस्तुओं को जीवित स्थान पर ले जाया जाता है, और जो बची हुई जगह बच जाती है उसे पुरानी पीढ़ी में ले जाया जाता है। युवा पीढ़ी को इकट्ठा किया जाता है।

जैसा कि वस्तुओं को पुरानी पीढ़ी में ले जाया जाता है, यह अंततः भर जाता है, और इसे इकट्ठा और जमा करना पड़ता है। अलग-अलग एल्गोरिदम इसके लिए अलग-अलग तरीके अपनाते हैं। उनमें से कुछ एप्लिकेशन थ्रेड्स को रोकते हैं (जो पुरानी पीढ़ी की तुलना में एक लंबे 'स्टॉप-द-वर्ल्ड' ठहराव की ओर जाता है) युवा पीढ़ी की तुलना में काफी बड़ा है), जबकि उनमें से कुछ इसे समवर्ती रूप से करते हैं जबकि एप्लिकेशन थ्रेड्स चलते रहते हैं। इस प्रक्रिया को पूर्ण जीसी कहा जाता है। ऐसे दो कलेक्टर हैंCMS and G1

आइए अब हम इन एल्गोरिदम का विस्तार से विश्लेषण करते हैं।

सीरियल जीसी

यह क्लाइंट-क्लास मशीनों (एकल प्रोसेसर मशीन या 32 बी जेवीएम, विंडोज) पर डिफ़ॉल्ट जीसी है। आमतौर पर, जीसी भारी रूप से गुणा किए जाते हैं, लेकिन धारावाहिक जीसी नहीं है। यह ढेर को संसाधित करने के लिए एक एकल धागा है, और जब भी यह मामूली जीसी या एक प्रमुख जीसी कर रहा है, तो यह एप्लिकेशन थ्रेड्स को रोक देगा। हम ध्वज को निर्दिष्ट करके इस GC का उपयोग करने के लिए JVM को कमांड कर सकते हैं:-XX:+UseSerialGC। यदि हम चाहते हैं कि यह कुछ अलग एल्गोरिथ्म का उपयोग करे, तो एल्गोरिथ्म नाम निर्दिष्ट करें। ध्यान दें कि पुरानी पीढ़ी एक बड़ी GC के दौरान पूरी तरह से संकुचित हो जाती है।

थ्रूपुट जीसी

यह जीसी 64 बी जेवीएम और मल्टी-सीपीयू मशीनों पर डिफ़ॉल्ट है। धारावाहिक जीसी के विपरीत, यह युवा और पुरानी पीढ़ी को संसाधित करने के लिए कई थ्रेड्स का उपयोग करता है। इस वजह से, GC को भी कहा जाता हैparallel collector। झंडे का उपयोग करके हम अपने जेवीएम को इस कलेक्टर का उपयोग करने की आज्ञा दे सकते हैं:-XX:+UseParallelOldGC या -XX:+UseParallelGC(जेडीके 8 के लिए बाद में)। एप्लिकेशन थ्रेड्स रोक दिए जाते हैं, जबकि यह एक प्रमुख या मामूली कचरा संग्रह करता है। सीरियल कलेक्टर की तरह, यह एक प्रमुख जीसी के दौरान युवा पीढ़ी को पूरी तरह से संकुचित करता है।

थ्रूपुट जीसी वाईजी और ओजी एकत्र करता है। जब एडेन भर जाता है, तो कलेक्टर इससे जीवित वस्तुओं को या तो ओजी या एक बचे स्थान (SS0 और SS1 के नीचे आरेख में) में से निकाल देता है। मृत वस्तुओं को उनके कब्जे वाले स्थान को मुक्त करने के लिए छोड़ दिया जाता है।

YG की जीसी से पहले

YG की GC के बाद

एक पूर्ण GC के दौरान, थ्रूपुट कलेक्टर पूरे YG, SS0 और SS1 को खाली करता है। ऑपरेशन के बाद, ओजी में केवल जीवित वस्तुएं होती हैं। हमें ध्यान देना चाहिए कि उपरोक्त दोनों कलेक्टर ढेर को संसाधित करते समय अनुप्रयोग थ्रेड्स को रोकते हैं। इसका अर्थ है एक प्रमुख GC के दौरान लंबे समय तक 'stopthe- world' रुकता है। अगले दो एल्गोरिदम का लक्ष्य उन्हें खत्म करना है, अधिक हार्डवेयर संसाधनों की कीमत पर -

सीएमएस कलेक्टर

यह 'समवर्ती मार्क-स्वीप' के लिए खड़ा है। इसका कार्य यह है कि यह पुरानी पीढ़ी के माध्यम से समय-समय पर स्कैन करने के लिए कुछ पृष्ठभूमि थ्रेड्स का उपयोग करता है और मृत वस्तुओं से छुटकारा दिलाता है। लेकिन एक मामूली जीसी के दौरान, एप्लिकेशन थ्रेड्स बंद हो जाते हैं। हालांकि, ठहराव काफी छोटा है। यह CMS को एक कम-ठहराव संग्राहक बनाता है।

इस कलेक्टर को एप्लिकेशन थ्रेड्स चलाते समय ढेर के माध्यम से स्कैन करने के लिए अतिरिक्त सीपीयू समय की आवश्यकता होती है। इसके अलावा, बैकग्राउंड थ्रेड्स केवल ढेर को इकट्ठा करते हैं और कोई कंपटीशन नहीं करते हैं। वे ढेर के टुकड़े हो सकते हैं। जैसा कि यह जारी है, एक निश्चित समय के बाद, सीएमएस सभी एप्लिकेशन थ्रेड्स को बंद कर देगा और एक एकल थ्रेड का उपयोग करके ढेर को कॉम्पैक्ट करेगा। CV कलेक्टर का उपयोग करने के लिए JVM को बताने के लिए JVM तर्कों का उपयोग करें -

“XX:+UseConcMarkSweepGC -XX:+UseParNewGC” जेवीएम ने सीएमएस कलेक्टर का उपयोग करने के लिए यह बताने के लिए तर्क दिया।

जीसी से पहले

जीसी के बाद

ध्यान दें कि संग्रह समवर्ती रूप से किया जा रहा है।

जी 1 जीसी

यह एल्गोरिथ्म ढेर क्षेत्रों को विभाजित करके काम करता है। सीएमएस कलेक्टर की तरह, यह मामूली जीसी करते समय एप्लिकेशन थ्रेड्स को रोकता है और एप्लिकेशन थ्रेड्स को चालू रखते हुए पुरानी पीढ़ी को संसाधित करने के लिए पृष्ठभूमि थ्रेड्स का उपयोग करता है। चूंकि इसने पुरानी पीढ़ी को क्षेत्रों में विभाजित किया है, इसलिए यह वस्तुओं को एक क्षेत्र से दूसरे क्षेत्र में ले जाते समय उन्हें संकुचित करता रहता है। इसलिए, विखंडन न्यूनतम है। आप ध्वज का उपयोग कर सकते हैं:XX:+UseG1GCइस एल्गोरिथ्म का उपयोग करने के लिए अपने JVM को बताने के लिए। सीएमएस की तरह, यह भी ढेर प्रसंस्करण और आवेदन धागे को समवर्ती चलाने के लिए अधिक CPU समय की आवश्यकता है।

इस एल्गोरिथ्म को बड़े ढेर (> 4 जी) को संसाधित करने के लिए डिज़ाइन किया गया है, जिन्हें कई अलग-अलग क्षेत्रों में विभाजित किया गया है। उन क्षेत्रों में से कुछ में युवा पीढ़ी शामिल है, और बाकी में पुराने शामिल हैं। पारंपरिक रूप से उपयोग करके YG को मंजूरी दे दी गई है - सभी एप्लिकेशन थ्रेड्स रोक दिए गए हैं और सभी ऑब्जेक्ट जो अभी भी पुरानी पीढ़ी या उत्तरजीवी स्थान के लिए जीवित हैं।

ध्यान दें कि सभी GC एल्गोरिदम ने ढेर को YG और OG में विभाजित किया है, और YG को साफ़ करने के लिए एक STWP का उपयोग करें। यह प्रक्रिया आमतौर पर बहुत तेज होती है।