我对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
答案 0 :(得分:4)
因为没有任何东西再引用对象并不意味着内存将被回收。垃圾收集器将在未来的某个时间运行,并且通常唯一的保证是它会在出现内存不足错误之前运行。
这里可能发生的另一件事是您正在查看Lisp进程内存使用情况。当内存为CG时,它通常不会返回到操作系统。相反,内存在堆上简单地标记为空闲,并且可以在将来的内存分配中使用。
答案 1 :(得分:1)
仅限SBCL ......
(gc :full t)
这将强行开启所有世代的垃圾收集。我注意到SBCL几天前保留了大量的内存并用它来降低内存的“真实”用量。
然后我写了一个ensure-gc宏来包装我的垃圾计算&实验性的东西。当我回到家的时候,如果我记得的话,我会把它粘贴进去......这没什么特别的。