compiled/eval'ed 过程的内存是否在 Chez Scheme 中被垃圾收集?

Is the memory of compiled/eval’ed procedures garbage-collected in Chez Scheme?

在运行时包含编译器的多种(也许是大多数)语言实现忽略了垃圾收集丢弃的代码(参见,例如 , where this leads to memory leaks in applications like

我的初步测试表明 Chez Scheme 不会在这里泄漏内存,但我想更确定地知道,因为我什至不知道 fg 实际上 得到编译。 (古老的口头禅:“测试只能证明错误的存在,而不是它们的不存在”)


我试过的测试:fg 互相调用,它们的定义在运行时被替换。

(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

鉴于过程和垃圾收集对 Scheme 的重要性,如果 Chez Scheme 不尝试垃圾收集 任何 动态创建的对象,我会感到惊讶。 R6RS Standard says [强调我的]:

All objects created in the course of a Scheme computation, including procedures and continuations, have unlimited extent. No Scheme object is ever destroyed. The reason that implementations of Scheme do not (usually!) run out of storage is that they are permitted to reclaim the storage occupied by an object if they can prove that the object cannot possibly matter to any future computation.

过程是一个对象,如果实现可以证明计算不再需要它,则任何对象都可能被垃圾回收。这不是必需的,但适用于任何对象,而不仅仅是程序。

Chez Scheme 手册似乎是权威的,尽管 (Chez Scheme Version 9 User's Guide, p. 82):

Since all Scheme objects, including code objects, can be relocated or even reclaimed by the garbage collector....

在 1990 年代,Kent Dybvig 与 David Eby 和 Carl Bruggeman 一起写了一篇论文,这篇论文可能很有趣,名为 Don’t Stop the BIBOP: Flexible and Efficient Storage Management for Dynamically Typed Languages,它描述了 Chez Scheme 中实现的垃圾收集策略。这篇论文花了一些时间讨论“代码对象”,特别是在垃圾收集过程中如何隔离和区别对待它们(因为它们可能包含指向其他对象的指针)。