Chez Scheme 中是不是对已编译/评估过的程序的内存进行了垃圾回收?
Posted
技术标签:
【中文标题】Chez Scheme 中是不是对已编译/评估过的程序的内存进行了垃圾回收?【英文标题】:Is the memory of compiled/eval’ed procedures garbage-collected in Chez Scheme?Chez Scheme 中是否对已编译/评估过的程序的内存进行了垃圾回收? 【发布时间】:2021-04-02 14:04:50 【问题描述】:在运行时包含编译器的多种(也许是大多数)语言实现会忽略垃圾收集丢弃的代码(例如,请参见 julia,其中 leads to memory leaks 在像 genetic-programming 这样的应用程序中)
我的初步测试表明 Chez Scheme 不会在这里泄漏内存,但我想更确定地知道,因为我什至不知道 f
和 g
是否实际上编译。 (古老的口头禅:“测试只能证明错误的存在,而不是它们的缺失”)
我尝试的测试:f
和 g
互相调用,它们的定义在运行时被替换。
(define f)
(define g)
(define (make-f x)
(eval `(set! f (lambda (y)
(if (> y 100)
(+ (remainder ,x 3) (g y))
(+ y 1))))))
(define (make-g x)
(eval `(set! g (lambda (y)
(if (< y 10)
(+ (remainder ,x 5) (f y))
(div y 2))))))
(define (make-and-run-f n)
(begin
(make-f 1)
(make-g 1)
(let loop ((i 0) (acc 0))
(if (> i n)
acc
(begin
(make-f i)
(make-g i)
(loop (+ i 1) (+ acc (f 33))))))))
(time (make-and-run-f 1000000)) ; runs in 10 min and negligible memory
【问题讨论】:
您的代码define
已经定义了绑定,因此它不是正确的标准方案并且结果未指定。在顶层定义它并在程序中使用set!
。
@Sylwester 已更新,谢谢。我依稀记得使用了一个没有redefine
的方案。开局?麻省理工学院?交互式开发因此而繁琐。
【参考方案1】:
鉴于过程和垃圾收集对 Scheme 的重要性,如果 Chez Scheme 没有尝试对 任何 动态创建的对象进行垃圾收集,我会感到惊讶。 R6RS Standard says [强调我的]:
在 Scheme 计算过程中创建的所有对象,包括过程和延续,都具有无限范围。没有任何 Scheme 对象被销毁。 Scheme 的实现不会(通常!)存储空间不足的原因是,如果他们能够证明对象不可能对任何未来的计算产生影响,他们就可以回收对象占用的存储空间。
过程是一个对象,如果实现可以证明计算不再需要它,任何对象都可能被垃圾回收。这不是要求,但适用于任何对象,而不仅仅是过程。
虽然(Chez Scheme Version 9 User's Guide, p. 82):
,Chez Scheme 手册似乎是权威的由于所有的 Scheme 对象,包括代码对象,都可以被垃圾收集器重新定位甚至回收......
在 1990 年代,Kent Dybvig 与 David Eby 和 Carl Bruggeman 一起写了一篇论文,这里可能会感兴趣,名为 Don’t Stop the BIBOP: Flexible and Efficient Storage Management for Dynamically Typed Languages,描述了 Chez Scheme 中实现的垃圾收集策略。在本文中,花了一些时间讨论“代码对象”,特别是在垃圾收集过程中如何隔离和区别对待它们(因为它们可能包含指向其他对象的指针)。
【讨论】:
以上是关于Chez Scheme 中是不是对已编译/评估过的程序的内存进行了垃圾回收?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Ubuntu 上安装 Petite Chez Scheme?