小编jfo*_*jfo的帖子

何时在lisp解释器中释放闭包的内存

我正在从头开始编写一个简单的lisp解释器.我有一个全局环境,在评估文件中的所有表单时绑定了顶级变量.当评估文件中的所有表单时,将释放顶级env和其中的所有键值数据结构.

当求值程序遇到lambda表单时,它会创建一个PROC包含3个内容的对象:应用过程时要绑定在本地框架中的参数列表,函数体,以及指向它所创建环境的指针.例如:

(lambda (x) x)
Run Code Online (Sandbox Code Playgroud)

会产生内部的东西,如:

PROC- args: x, 
      body: x, 
      env: pointer to top level env
Run Code Online (Sandbox Code Playgroud)

当PROC被施加时,用于帧创造了一个新的环境和本地绑定上演那里,以允许主体与适当的绑定进行评估.此框架环境包含指向其闭包的指针,以允许在THAT内部进行变量查找.在这种情况下,那将是全球环境.在PROC评估主体之后,我可以释放与其相关的所有单元格,包括其框架环境,并且在没有内存泄漏的情况下退出.

我的问题是更高阶的功能.考虑一下:

(define conser 
    (lambda (x)
        (lambda (y) (cons x y))))
Run Code Online (Sandbox Code Playgroud)

一个函数,它接受一个参数并产生另一个函数,该函数将该参数包含在您传递给它的内容中.所以,

(define aconser (conser '(1)))
Run Code Online (Sandbox Code Playgroud)

会产生一个'(1)与传递给它的东西相符的函数.例如:

(aconser '(2)) ; ((1) 2) 
Run Code Online (Sandbox Code Playgroud)

我的问题是aconser必须保留指向它所创建环境的指针,即conser通过调用生成的时间(conser '(1)).当aconser该PROC应用,它的框架必须指向的框架conser,当存在aconser被定义,所以我不能自由的框架conser应用它之后.我不知道如何/最好的方法来释放与lambda帧相关的内存,并且还支持这种持久的高阶函数.

我可以想到一些解决方案:

  • 某种类型的ARC

  • 在生成时将封闭环境复制到评估的PROC的框架中

这似乎是这里隐含的内容.因此,而不是保存在PROC对象的指针,它的关闭,我想...复制封闭环境和存储指向的是 直接在单元格?这不只是将罐头更深一层并导致同样的问题吗?

  • 在高阶函数体内的读取时间递归地替换标签

我担心我可能会遗漏一些非常简单的东西,而且我很好奇这个过程如何在lisp和其他语言的其他实现中得到支持.我没有太多的运气寻找答案,因为这个问题非常具体,甚至对于这个实施(我承认我只是脱离了我的帽子作为学习项目)而且我能够找到的大部分内容只是解释了细节从正在实现的语言的闭包,而不是从语言实现的语言.

如果有帮助的话,这里是我的源代码中相关行 …

lisp interpreter memory-management

5
推荐指数
1
解决办法
110
查看次数

标签 统计

interpreter ×1

lisp ×1

memory-management ×1