【问题标题】:Memory leak in SBCL's REPLSBCL 的 REPL 中的内存泄漏
【发布时间】:2012-02-18 16:25:56
【问题描述】:

我对 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

【问题讨论】:

  • 您可能想在 SBCL 邮件列表中提出这个问题
  • ... 并且可能会在此处发布他们回复的后续内容。顺便说一句,为什么问题标题中有“关闭”?我在问题的代码中没有看到任何闭包。
  • 我在 CLISP 中尝试过相同的代码,没有问题。 SBCL的git版本还是有这个问题,所以我提交了一个bug报告:(bugs.launchpad.net/sbcl/+bug/936304)。关于关闭备注,没有关闭:)
  • 正如我在该错误报告中提到的,该错误仍然存​​在,尽管标记为已关闭。我也报告了类似的bugs.launchpad.net/sbcl/+bug/1009267。开发人员似乎对这些问题非常不感兴趣(而且令人不安),尽管在我看来这是一个重大问题。

标签: memory-leaks common-lisp sbcl


【解决方案1】:

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

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

【讨论】:

  • 有效积分,我没有想到。所以我做了进一步的测试:评估(add-one (test-gc)) 几次。如果任何一点都有效,那么我永远不会耗尽内存。但是,经过几次评估后,我得到了:“堆耗尽”。所以看起来内存并没有被释放或重用。
  • 我在 Linux 上的 SBCL 1.0.53 中没有看到这个问题
  • 有趣。我用的是 1.0.54。我刚刚尝试了 1.0.53,但我仍然得到错误(也在 Linux 上)。如果你在 git 版本中也没有出现错误,你可以考虑分享到 (bugs.launchpad.net/sbcl/+bug/936304)。
【解决方案2】:

仅 SBCL...

(gc :full t)

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

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

【讨论】:

  • 强制垃圾收集有效,但只有在我多次评估 (add-one (test-gc)) 之后。好笑。
  • @Andrei:我必须传入 :full 以确保它经过所有世代。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-01
  • 2010-12-20
  • 2020-05-26
  • 2012-08-20
  • 2017-10-14
  • 2019-09-05
相关资源
最近更新 更多