- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
为什么这段代码会溢出 CMUCL 堆?即使我给它 400MB 内存 (setq extensions:*bytes-consed-between-gcs* 400000000)
CMUCL 仍然会卡住。
; [GC threshold exceeded with 12,012,544 bytes in use. Commencing GC.]
; [GC completed with 188,064 bytes retained and 11,824,480 bytes freed.]
; [GC will next occur when at least 400,188,064 bytes are in use.]
; [GC threshold exceeded with 400,202,280 bytes in use. Commencing GC.]
; [GC completed with 207,120 bytes retained and 399,995,160 bytes freed.]
; [GC will next occur when at least 400,207,120 bytes are in use.]
此代码在 CCL 和 SBCL 上运行正常,但我没有查看它们的内存使用情况。
这是 CMUCL 中的错误吗??我相信所有这些函数都是尾递归的。
(defun sqrt-iter (guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))
(defun improve (guess x)
(average guess (/ x guess)))
(defun average (x y)
(/ (+ x y) 2))
(defun good-enough? (guess x)
(< (abs (- (* guess guess) x)) 0.001))
(defun mysqrt (x)
(sqrt-iter 1.0 x))
(defun zint (x acc step)
(setq num-iter (+ 1 num-iter))
(if (>= x 10000.0)
acc
(zint (+ x step)
(+ acc (* step (mysqrt x)))
step)))
(setq num-iter 0)
(format t "result=~A; iterations=~A~%" (zint 0.0 0.0 .001) num-iter)
(quit)
编辑:是的,CMUCL 确实付出了很多不必要的代价。试试这个简单的例子:
$ ~/cmucl/bin/lisp
...
* (defun foo () (bar))
FOO
* (defun bar () (foo))
BAR
* (foo)
; [GC threshold exceeded with 12,009,008 bytes in use. Commencing GC.]
; [GC completed with 111,816 bytes retained and 11,897,192 bytes freed.]
; [GC will next occur when at least 12,111,816 bytes are in use.]
; [GC threshold exceeded with 12,120,912 bytes in use. Commencing GC.]
; [GC completed with 120,016 bytes retained and 12,000,896 bytes freed.]
; [GC will next occur when at least 12,120,016 bytes are in use.]
; [GC threshold exceeded with 12,133,576 bytes in use. Commencing GC.]
最佳答案
有两个函数是“尾递归”的:sqr-iter 和 zint。
一般建议:
为了让编译器优化这些,DEBUG 优化级别需要为 2 或更低。
你可以通过反汇编看编译器是否生成尾递归代码。使用函数反汇编
。
GC 调用本身不是问题。大多数实现不会在 GC 上打印任何内容。 CMUCL 默认打印它 (IIRC)。 CMUCL 可能会为未优化的代码分配大量 float - 这可能会导致大量 GC。
只有当 CMUCL 出现堆栈溢出时,您才会看到尾调用优化不起作用。 GC 本身仅显示大量 consing。
因此,要调试您的问题,您首先需要查看代码是否在编译时启用了尾调用优化。你可以反汇编代码。另一种选择是在运行时将代码放入调试器,然后查看堆栈回溯。在堆栈上不应该有大量的递归调用——它们将被跳转代替。
如果代码以恒定的堆栈空间运行,那么您需要查看 float 的分配。然后您需要检查代码没有分配太多 float 。
关于lisp - CMUCL 的奇怪 GC 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15436990/
为什么这段代码会溢出 CMUCL 堆?即使我给它 400MB 内存 (setq extensions:*bytes-consed-between-gcs* 400000000) CMUCL 仍然会卡住
如 a macro-related question I recently posted to SO 中的建议,我通过调用函数编写了一个名为“快速”的宏 (here is the standalone
我正在使用 debian stretch 并从稳定存储库安装 CMUCL。尝试以下操作时 (run-program "sh" '("ls") :output T) 我明白了 # 没有预期的输出。有什么
我是一名优秀的程序员,十分优秀!