2016-05-21 11 views
5

में बंद करने की स्मृति को मुक्त करने के लिए मैं स्क्रैच से एक सरल लिस्पी दुभाषिया लिख ​​रहा हूं। मेरे पास एक वैश्विक वातावरण है कि फ़ाइल में सभी रूपों के मूल्यांकन के दौरान शीर्ष स्तर चर शामिल हैं। जब फ़ाइल के सभी रूपों का मूल्यांकन किया गया है, तो शीर्ष स्तर env और इसके अंदर के सभी महत्वपूर्ण मूल्य डेटा structs को मुक्त कर दिया गया है। समारोह के मुख्य भाग, और करने के लिए एक सूचक जब प्रक्रिया लागू किया जाता है तर्क एक स्थानीय फ्रेम में बंधे होने के लिए की एक सूची,:जब एक लिस्पी दुभाषिया

मूल्यांकनकर्ता एक lambda रूप का सामना करना पड़ता है, यह एक PROC उद्देश्य यह है कि 3 चीजें शामिल हैं बनाता है परिवेश में वह बनाया गया था उदाहरण के लिए:।

PROC- args: x, 
     body: x, 
     env: pointer to top level env 

जब PROC लागू किया जाता है, एक नया वातावरण फ्रेम और वें के लिए बनाई गई है:

(lambda (x) x) 

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

मेरी समस्या उच्च आदेश कार्यों के साथ है। इस पर विचार करें:

(define conser 
    (lambda (x) 
     (lambda (y) (cons x y)))) 

एक समारोह है कि एक तर्क लेता और एक अन्य समारोह का उत्पादन है कि विपक्ष होगा कुछ आप इसे में पारित करने के लिए है कि तर्क। तो,

(define aconser (conser '(1))) 

एक समारोह है कि जो कुछ इसे में पारित हो जाता है के लिए '(1) cons'es प्राप्त करेगी। पूर्व:

(aconser '(2)) ; ((1) 2) 

यहाँ मेरी समस्या यह है कि aconser परिवेश में वह बनाया गया था, अर्थात् कि conser की जब है मंगलाचरण (conser '(1)) के माध्यम से उत्पादन किया गया था करने के लिए एक सूचक को बनाए रखने चाहिए। जब aconserPROC लागू किया गया है, तो इसके फ्रेम को conser के फ्रेम पर इंगित करना चाहिए जो aconser परिभाषित किया गया था, इसलिए मैं इसे लागू करने के बाद conser के फ्रेम को मुक्त नहीं कर सकता। मुझे नहीं पता कि यह लागू होने पर लैम्ब्डा फ्रेम से जुड़े स्मृति को मुक्त करने का सर्वोत्तम तरीका कैसे है और इस तरह के लगातार उच्च आदेश फ़ंक्शन का भी समर्थन करता है।

मैं कुछ समाधान के बारे में सोच सकते हैं:

  • एआरसी

  • किसी प्रकार का मूल्यांकन PROC के फ्रेम में संलग्न पर्यावरण को कॉपी जब यह उत्पादन किया है

यह ऐसा लगता है कि here को क्या बताया जा रहा है। तो, प्रोसी ऑब्जेक्ट में बंद होने के लिए पॉइंटर को सहेजने के बजाय, मैं ... बंद वातावरण को प्रतिलिपि बनाउंगा और पर 0 सूचकांक को पर पॉइंटर स्टोर करूँगा? क्या यह सिर्फ एक स्तर को गहराई से लात मारना नहीं होगा और परिणामस्वरूप एक ही समस्या होगी?

  • रिकर्सिवली उच्च आदेश समारोह के शरीर के अंदर पढ़ने समय में लेबल प्रतिस्थापन

मैं चिंतित मैं यहाँ बहुत ही सरल कुछ कमी हो सकती है, और यह भी मैं कैसे इस प्रक्रिया के रूप में उत्सुक हूँ सामान्य रूप से बंद होने के साथ लिस्प और अन्य भाषाओं के अन्य कार्यान्वयन में समर्थित है। मुझे जवाबों की तलाश में बहुत भाग्य नहीं मिला है क्योंकि सवाल बहुत ही विशिष्ट है, शायद इस कार्यान्वयन के लिए भी (कि मैं स्वीकार्य रूप से सिर्फ एक सीखने की परियोजना के रूप में अपनी टोपी खींच रहा हूं) और जो कुछ मैं ढूंढने में सक्षम हूं वह केवल विवरण बताता है भाषा को कार्यान्वित किया जा रहा है, इस भाषा से नहीं, जिस भाषा में भाषा लागू की जा रही है।

Here is a link मेरे स्रोत में प्रासंगिक रेखा के लिए, यदि यह सहायक है, और मुझे यह विस्तार करने में प्रसन्नता हो रही है कि यह प्रश्न पूरी तरह से समस्या का वर्णन करने के लिए पर्याप्त विस्तृत नहीं है। धन्यवाद!

+1

मुझे कुछ याद आ रहा है, लेकिन आप कहते हैं "प्रोसी बॉडी का मूल्यांकन करने के बाद, मैं इसके साथ जुड़े सभी कोशिकाओं को अपने फ्रेम वातावरण सहित मुक्त कर सकता हूं, और बिना किसी स्मृति रिसाव से बाहर निकल सकता हूं।" क्या आप कई बार बंद करने का पुन: उपयोग नहीं कर सकते? इस मामले में आप पर्यावरण को बहुत जल्दी मुक्त करने जा रहे हैं। – coredump

+0

यह बिल्कुल समस्या है।मैं बंद होने के बीच यहां एक भेद खींच रहा हूं (जो भी env एक lambda eval'd होता है, जिसके परिणामस्वरूप एक proc) होता है और फ्रेम, जो लागू होने पर एक प्रो के लिए आंतरिक चर के स्थानीय बाध्यकारी होता है। मैं इन शर्तों को ऐतिहासिक रूप से गलत समझा सकता हूं ... – jfo

+0

इसलिए यदि मेरे पास एक लैम्ब्डा है जो केवल एक स्तर का गहरा है, तो प्रत्येक फ्रेम को लागू होने पर इसका फ्रेम हर बार फिर से बनाया जाता है। – jfo

उत्तर

1

आमतौर पर इसे निष्क्रिय दुभाषियों में संभाला जाने वाला तरीका कचरा-संग्राहक (जीसी) का उपयोग करना और जीसीएड ढेर में अपने सक्रियण फ्रेम आवंटित करना है। तो आप उन फ्रेमों को स्पष्ट रूप से मुक्त नहीं करते हैं, आप लागू होने पर जीसी को मुक्त करते हैं। ,

  • जब एक बंद बनाई गई है वर्तमान पर्यावरण के लिए एक सूचक की दुकान नहीं है:

    अधिक परिष्कृत कार्यान्वयन में, आप एक अलग दृष्टिकोण का उपयोग कर सकते हैं। इसके बजाय, बंद करने के द्वारा उपयोग किए जाने वाले उन चर के मान की प्रतिलिपि बनाएँ (इसे लैम्ब्डा के मुक्त चर कहा जाता है)। और उन चर के लिए पर्यावरण को देखने के बजाय उन प्रतियों का उपयोग करने के लिए बंद करने के शरीर को बदलें। इसे बंद रूपांतरण कहा जाता है।

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

अधिक परिष्कृत कार्यान्वयन भी लाभ है कि यह अंतरिक्ष अर्थ विज्ञान के लिए एक सुरक्षित प्रदान कर सकता है: एक बंद ही डेटा पर पकड़ होगा जो यह वास्तव में अनुभवहीन दृष्टिकोण जहां बंद अंततः पहुंचते हैं, पर इसके विपरीत करने के लिए पूरे आस-पास के माहौल का जिक्र करते हुए और इसलिए जीसी को उस डेटा को इकट्ठा करने से रोक सकता है जिसे वास्तव में संदर्भित नहीं किया जाता है, लेकिन बंद होने पर उस समय पर्यावरण में होना ही हुआ था।

+0

ty, यह एक संपूर्ण जवाब है और मूल रूप से मुझे दर्शाता है कि मेरे पोस्ट-पूछे जाने वाले शोध ने मुझे क्या दिखाया। मेरे खिलौने के लिए, मैंने फैसला किया कि जीसी मेरी मूल परियोजना के दायरे से बाहर था और इसलिए मैंने इसे लागू नहीं किया, लेकिन मैं अपने अगले प्रयास पर योजना बनाने की योजना बना रहा हूं :) – jfo

+0

आप [यहां] के साथ समाप्त होने के बारे में पढ़ सकते हैं (http://blog.jfo.click/sild-is-a-lisp-dialect/)। – jfo

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