我正在从头开始编写一个简单的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