2010-06-04 5 views
12

में कचरा संग्रह जावा के विपरीत, पर्ल कचरा संग्रह के लिए संदर्भ गणना का उपयोग करता है। मैंने कुछ पिछले प्रश्नों की खोज करने की कोशिश की है जो सी ++ आरएआईआई और स्मार्ट पॉइंटर्स और जावा जीसी के बारे में बात करते हैं लेकिन समझ में नहीं आया कि पर्ल सर्कुलर रेफरेंसिंग समस्या से कैसे निपटता है।पर्ल

क्या कोई बता सकता है कि पर्ल के कचरा कलेक्टर सर्कुलर संदर्भों से कैसे निपटता है? सर्कुलर संदर्भित स्मृति को पुनः प्राप्त करने का कोई तरीका है जिसका अब प्रोग्राम द्वारा उपयोग नहीं किया जाता है या क्या पर्ल सिर्फ इस समस्या को पूरी तरह से अनदेखा करता है?

उत्तर

13

प्रोग्रामिंग पर्ल 3 एड की मेरी प्रति के अनुसार।, बाहर निकलने पर पर्ल 5 परिपत्र संदर्भों को पुनः प्राप्त करने के लिए "महंगा चिह्न और स्वीप" करता है। आप परिपत्र संदर्भों से जितना संभव हो सके से बचना चाहेंगे क्योंकि अन्यथा कार्यक्रम से बाहर निकलने तक उन्हें पुनः दावा नहीं किया जाएगा।

पर्ल 5 Scalar::Utils मॉड्यूल के माध्यम से कमजोर संदर्भ प्रदान करता है।

पर्ल 6 एक प्लग करने योग्य कचरा एकत्रित योजना (अच्छी तरह से, underlying VM will have multiple garbage collection options पर ले जाएगा और उन विकल्पों का व्यवहार पर्ल पर प्रभाव डाल सकता है)। यही है, आप विभिन्न कचरा कलेक्टरों के बीच चयन करने में सक्षम होंगे, या अपना खुद का कार्यान्वयन कर सकेंगे। एक प्रतिलिपि कलेक्टर चाहते हैं? ज़रूर। एक रंग कलेक्टर चाहते हैं? आपको यह मिला। मार्क/स्वीप, कॉम्पैक्टिंग इत्यादि? क्यों नहीं?

+4

नाइट: पर्ल 5 संदर्भ गिनती का उपयोग करता है। यह एक कचरा संग्रह योजना है। – tsee

+0

ठीक है, मैंने पर्ल 6 कचरा संग्रह के संदर्भ में संशोधन किया है। –

+1

उत्तर अपडेट करने के लिए धन्यवाद। एनबी: प्लग करने योग्य कचरा कलेक्टर एक भयानक विचार की तरह लग रहा है। चीजों को धीमा करने और/या कचरा कलेक्टरों को प्लग करने के दौरान दूरी पर संदिग्ध कार्रवाई का एक शानदार तरीका है जो जीसी समय के बारे में अलग-अलग वादे करता है। – tsee

-8

सर्कुलर संदर्भों को पुनः प्राप्त करने के लिए पर्ल कुछ मौकों पर एक मार्क-एंड-स्वीप वैकल्पिक जीसी लागू करता है (जब थ्रेड मर जाता है, मुझे लगता है)। ध्यान दें कि "प्रत्येक मान एक स्ट्रिंग है" पर्ल स्टांजा सच परिपत्र संदर्भ बनाना मुश्किल बनाता है; यह व्यवहार्य है, लेकिन "सामान्य" पर्ल कोड नहीं है, यही कारण है कि संदर्भ गिनती पर्ल के साथ अच्छी तरह से काम करती है।

+0

एक एसवी पर्ल कॉल को रिसाव करने का त्वरित तरीका 'सब रिसाव {मेरा $ आर; $ आर = \ $ आर; } ' हालांकि यह एक संक्षिप्त उदाहरण है, इसे ध्यान में रखे बिना समकक्ष करना मुश्किल नहीं है। –

+7

यह सादा गलत है; पर्ल * नहीं * मानता है कि हर मूल्य एक स्ट्रिंग है। 'मेरा $ हैशफ = {ए => 1};' 'hhref' को वास्तविक संदर्भ के रूप में छोड़ देता है, स्ट्रिंग नहीं। यह पर्ल 5 के बाद से सच रहा है, जो अक्टूबर 1 99 4 ** - 17 साल पहले आया था। (बेशक, पर्ल खुशी से संदर्भ को एक स्ट्रिंग में परिवर्तित कर देगा, लेकिन वह रूपांतरण एक तरफा है) – derobert

2

त्वरित उत्तर यह है कि पर्ल 5 स्वचालित रूप से परिपत्र संदर्भों को संभालता है। जब तक आप अपने कोड में स्पष्ट उपाय नहीं करते हैं, तब तक आपके किसी भी डेटा संरचना जिसमें परिपत्र संदर्भ शामिल होते हैं, उन्हें तब तक पुनः दावा नहीं किया जाएगा जब तक उन्हें थ्रेड नहीं बनाया जाता है। इसे एक स्वीकार्य ट्रेडऑफ माना जाता है जिसमें यह रनटाइम कचरा संग्रह की आवश्यकता से बचाता है जो निष्पादन को धीमा कर देगा।

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

उदाहरण:

use Scalar::Util qw(weaken); 

... 

    my $new_node = { content => $content, root => $root_node }; 
    weaken $new_node->{root}; 
    push @{$root_node->{children}}, $new_node; 

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