3

我对 REPL 中 SBCL 垃圾收集器的以下行为感到有些困惑。定义两个函数:

(defun test-gc ()
  (let ((x (make-array 50000000)))
    (elt x 0)))

(defun add-one (x) (+ 1 x))

然后运行

(add-one (test-gc))

我希望不再引用原始数组。然而,正如(房间)报告的那样,内存没有被释放。我会理解,如果我直接运行 (test-gc),那么某些引用可能会卡在 SLIME 或

(list * ** ***)

但是这里是这样吗?谢谢,安德烈。

更新前段时间我提交了一个错误。最近得到了证实。见: https ://bugs.launchpad.net/sbcl/+bug/936304

4

2 回答 2

4

仅仅因为不再引用对象并不意味着内存将被回收。垃圾收集器将在未来的某个时间运行,并且通常唯一的保证是它会在出现内存不足错误之前运行。

这里可能发生的另一件事是您正在查看 Lisp 进程内存使用情况。当内存被 CG'ed 时,它通常不会返回给操作系统。相反,内存在堆上被简单地标记为空闲,并且可以在未来的内存分配中使用。

于 2012-02-18T17:07:39.963 回答
1

仅 SBCL...

(gc :full t)

这将强制启动所有代的垃圾收集。我注意到几天前 SBCL 持有大量内存,并使用它来将内存降低到“真实”使用情况。

然后我写了一个 ensure-gc 宏来包装我的垃圾计算和实验的东西。如果我记得的话,我会在回家的时候把它贴进去……这没什么花哨的。

于 2012-02-21T00:06:24.453 回答