我正在從頭開始編寫一個簡單的lisp解釋器。我有一個全局環境,在評估文件中的所有表單時,頂級變量都會被綁定。當文件中的所有表單都被評估過時,頂層env和其中的所有鍵值數據結構都被釋放。何時在lisp解釋器中釋放閉包的內存
當評估者遇到lambda
表單時,它會創建一個包含3件東西的PROC
對象:應用過程時要在本地框架中綁定的參數列表,該函數的主體以及指向環境它是在創建,例如:
將產生什麼樣的內部:
PROC- args: x,
body: x,
env: pointer to top level env
當施加PROC
中,爲幀和第創建了一個新的環境本地綁定將在那裏進行,以允許使用適當的綁定來評估身體。這個框架環境包含一個指向它的閉包的指針,以允許在THAT中進行變量查找。在這種情況下,這將是全球環境。在對PROC
正文進行評估後,我可以釋放與其關聯的所有單元格,包括其框架環境,並退出時不會發生內存泄漏。
我的問題是高階函數。試想一下:
(define conser
(lambda (x)
(lambda (y) (cons x y))))
它有一個參數,併產生另一個函數的函數,將利弊這樣的說法你進入它的東西。所以,
(define aconser (conser '(1)))
將產生該cons'es '(1)
到任何被傳遞到它的功能。例如:
(aconser '(2)) ; ((1) 2)
我在這裏的問題是,aconser
必須保留一個指向其創建的環境中,即中conser
時通過調用(conser '(1))
製作。當aconser
應用PROC
時,其幀必須指向定義爲aconser
時存在的conser
的幀,因此在應用它之後我不能釋放conser
的幀。我不知道在應用時如何釋放與lambda框架相關聯的內存,並且還支持這種持久高階函數。
我能想到的一些解決方案的:
某種類型的ARC
的複製封閉環境到評價PROC的幀時,它產生
這似乎暗示here。因此,我不會將一個指針保存在PROC對象中,而是將它關閉,我會......複製閉包環境,並將指針直接存儲在單元格中的?這不僅僅是踢一個更深的水平,導致同樣的問題?
- 遞歸代高階函數體內部在讀取時間標籤
我擔心我可能失去了一些東西很簡單,我也很好奇,怎麼這個程序在其他lisp語言和其他通常使用閉包的語言中得到支持。我沒有太多的運氣來尋找答案,因爲問題是非常具體的,甚至可能是這個實現(我承認我只是作爲一個學習項目脫離了我的帽子),而我能找到的大部分內容只是解釋了具體情況從語言實施的角度來看,而不是語言正在實施的語言。
Here is a link到我的來源的相關行,如果它是有用的,我很高興闡述,如果這個問題不夠詳細,足以描述問題徹底。謝謝!
我可能會遺漏一些東西,但是你說:「在評估PROC體之後,我可以釋放與它相關的所有單元格,包括它的框架環境,並退出時沒有內存泄漏。」。你不能多次重複使用閉包嗎?在這種情況下,您將過早釋放環境。 – coredump
這正是問題所在。我在這裏區分了閉包(無論env是一個lambda是否已經被eval了,導致一個proc)和框架,這是一個proc內部變量在應用時的本地綁定。我可能會誤解這些術語,雖然... – jfo
因此,如果我有一個只有單層深度的lambda表達式,每次應用它時都會重新創建它的框架,並使用傳遞給它的任何參數。 – jfo