2011-12-12 27 views
7

मैंने हाल ही में कचरा संग्रह (ज्यादातर जावा में) के बारे में बिट्स और टुकड़े पढ़े हैं और एक प्रश्न अभी भी अनुत्तरित नहीं है: एक जेवीएम (या सामान्य रूप से रनटाइम सिस्टम) वर्तमान में जीवित वस्तुओं का ट्रैक कैसे रखता है?कचरा संग्रह - रूट नोड्स

मैं समझता हूं कि ऑब्जेक्ट्स वे हैं जो वर्तमान में स्टैक पर हैं, इसलिए सभी स्थानीय चर या फ़ंक्शन पैरामीटर, जो ऑब्जेक्ट हैं। इस दृष्टिकोण के साथ लूट यह है कि जब भी रनटाइम सिस्टम स्टैक पर वर्तमान में क्या जांचता है, तो संदर्भ संदर्भ और सरल int के बीच यह अंतर कैसे होगा? यह नहीं कर सकता, है ना?

इसलिए, तंत्र को लाइव वस्तुओं की प्रारंभिक सूची बनाने के लिए क्रम निशान स्वीप चरण के लिए पारित करने के लिए अनुमति देने के लिए किसी प्रकार का होना चाहिए ...

उत्तर

4

मुझे ग्रेफायर द्वारा प्रदान किया गया उत्तर गलत है। जेवीएम रनटाइम स्टैक पर डेटा को धक्का देने के लिए बाइटकोड का उपयोग करके देखे जाने पर रूट सेट को स्टैक से इकट्ठा नहीं करता है। ढेर फ्रेम में 4 बाइट (32 बिट आर्क) स्लॉट होते हैं। प्रत्येक स्लॉट एक हीप ऑब्जेक्ट या एक इंटीरियर जैसे आदिम मूल्य का संदर्भ हो सकता है। जब एक जीसी की आवश्यकता होती है, तो रनटाइम ढेर को ऊपर से नीचे तक स्कैन करता है। प्रत्येक स्लॉट के लिए, इसमें एक संदर्भ होता है यदि:

ए। यह 4 बाइट सीमा पर गठबंधन है।

बी। ढेर के क्षेत्र में ढेर बिंदु (मूल्य निचले और ऊपरी बाउंड के बीच)।

सी। आवंटन सेट है। आवंटन एक झंडा है जो दर्शाता है कि इसके अनुरूप स्मृति स्थान आवंटित है या नहीं।

मेरा संदर्भ यहां है: http://www.ibm.com/developerworks/ibm/library/i-garbage2/

रूट सेट (जावा में नहीं) खोजने के लिए कुछ अन्य तकनीकें हैं। उदाहरण के लिए, क्योंकि पॉइंटर्स आमतौर पर 4/8 बाइट सीमा पर गठबंधन होते हैं, पहली बिट का उपयोग यह इंगित करने के लिए किया जा सकता है कि स्लॉट एक आदिम मूल्य या सूचक है: आदिम मानों के लिए, पहला बिट 1 पर सेट किया गया है। इसका नुकसान कि आपके पास पूर्णांक का प्रतिनिधित्व करने के लिए केवल 31 बिट (32 बिट्स आर्क) हैं, और आदिम मूल्यों पर प्रत्येक संचालन में स्थानांतरण शामिल है, जो एक उपरि है।

इसके अलावा, आप ढेर पर आवंटित int सहित सभी प्रकार के सभी प्रकार कर सकते हैं। यही है, सभी चीजें वस्तुएं हैं। फिर एक ढेर फ्रेम में सभी स्लॉट तो संदर्भ हैं।

+0

तो सभी में यह JVM की बजाय बहुत कम स्तर भिन्नता है? लेकिन जेवीएम में बाइटकोड के लिए एक संदर्भ प्रकार घोषित किया गया है, तो इसका उपयोग क्यों न करें? आप सुनिश्चित हैं कि बाइट कोड स्तर के बजाय यह इतना कम स्तर है? – Bober02

+1

जैसा कि मुझे पता है (दोनों लिंक जो मैंने पहले दिया था, और कई जेवीएम कार्यान्वयन के कोड की ब्राउज़िंग के आधार पर), मुझे यकीन है कि मेरी समझ सही है। आप इसे देखने के लिए बस कुछ ओपन सोर्स जेवीएम कार्यान्वयन के जीसी कोड में डाइविंग कर सकते हैं। संदर्भ को जानने के लिए उन्हें सभी को ढेर चलने की जरूरत है। हालांकि, हो सकता है कि मानदंड यह सत्यापित करने के लिए प्रयोग किया जाता है कि स्लॉट संदर्भ है या नहीं, थोड़ा अंतर है (उनमें से अधिकतर ए और बी को सत्यापित करते हैं। सी के लिए, यह वास्तव में कार्यान्वयन पर आधारित है)। – Rainfield

+0

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

2

क्रम पूरी तरह से, संदर्भ चर और पुरातन के बीच अंतर कर सकते हैं कि है, क्योंकि संकलित बाइटकोड में।

उदाहरण के लिए यदि कोई फ़ंक्शन f1 फ़ंक्शन f2 (int i, ऑब्जेक्ट ओ, लांग एल) कहता है, तो कॉलिंग फ़ंक्शन f1 स्टैक (या एक रजिस्टर में) 4, या 8 का प्रतिनिधित्व करने वाले 4 बाइट्स को दबाएगा?) ओ के संदर्भ के लिए बाइट्स, और एल के लिए 8 बाइट्स। बुलाया गया फ़ंक्शन f2 जानता है कि स्टैक पर इन बाइट्स को कहां ढूंढना है, और संभावित रूप से ढेर पर किसी ऑब्जेक्ट के संदर्भ को प्रतिलिपि बना सकता है या नहीं। जब फ़ंक्शन f2 लौटाता है, तो कॉलिंग फ़ंक्शन पैरामीटर को स्टैक से छोड़ देगा।

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

http://www.javacoffeebreak.com/articles/thinkinginjava/abitaboutgarbagecollection.html के अनुसार, जावा tracing garbage collector का उपयोग करता है और संदर्भ गणना एल्गोरिदम नहीं करता है।

+0

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

+0

गहराई से विच्छेदन के लिए आलेख लिंक देखें। – greyfairer

+0

मुझे आपके द्वारा संदर्भित आलेख में निम्नलिखित वाक्य मिला है 'मार्क और स्वीप स्टैक और स्थिर स्टोरेज से शुरू होने के समान तर्क और लाइव ऑब्जेक्ट्स खोजने के लिए सभी हैंडल के माध्यम से ट्रेसिंग का पालन करता है।' इन रहस्यवादी हैंडल वे क्या हैं ... – Bober02

0

हॉटस्पॉट वीएम प्रत्येक सबराउटिन संकलित के लिए एक जीसी मानचित्र उत्पन्न करता है जिसमें जड़ों के बारे में जानकारी होती है।उदाहरण के लिए, मान लीजिए यह मशीन कोड के लिए एक सबरूटीन तैयार की है जो 120 बाइट्स लंबा है (सिद्धांत बाइट कोड के लिए एक ही है), तो इसके लिए जीसी नक्शा कुछ इस तरह दिखाई दे सकता है:

0 : [RAX, RBX] 
4 : [RAX, [RSP+0]] 
10 : [RBX, RSI, [RSP+0]] 
... 
120 : [[RSP+0],[RSP+8]] 

यहाँ [RSP+x] है स्टैक स्थानों और R?? रजिस्ट्रारों को इंगित करना चाहिए। तो अगर ऑफसेट 10 में असेंबली निर्देश पर थ्रेड बंद हो जाता है और एक जीसी चक्र चलता है तो हॉटस्पॉट जानता है कि तीन जड़ें RBX, RSI और [RSP+0] में हैं। यह उन जड़ों का पता लगाता है और पॉइंटर्स को अद्यतन करता है अगर इसे वस्तुओं को स्थानांतरित करना होता है।

जीसी मानचित्र के लिए मैंने जो प्रारूप वर्णन किया है वह सिर्फ सिद्धांत का प्रदर्शन करने के लिए है और स्पष्ट रूप से एक हॉटस्पॉट वास्तव में उपयोग नहीं करता है। यह पूर्ण नहीं है क्योंकि इसमें रजिस्टरों और स्टैक स्लॉट्स के बारे में जानकारी नहीं है जिसमें आदिम लाइव मान होते हैं और यह प्रत्येक निर्देश ऑफसेट के लिए सूची का उपयोग करने के लिए अंतरिक्ष कुशल नहीं है। ऐसे कई तरीके हैं जिनमें आप जानकारी को अधिक कुशल तरीके से पैक कर सकते हैं।