1

我的应用程序将给定的数据转换为树表示,它使用了太多的内存。因为它设法在崩溃之前将大约 200-300MB 的内存变成大约 3GB。

我现在想弄清楚泄漏在哪里,程序的哪一部分导致了泄漏。

因此,我现在想知道在 common-lisp 中使用 sbcl 进行内存分析最常见和最有效的技术是什么?

我已经看过了(room)(time)但是它的输出很冗长,我需要的只是一个包装器,它会说“执行后整体内存使用量为 +1000Byte”,这可以解决问题,因为我只想知道内存在哪里用过的。另一个标准是它必须“即时”工作,因为应用程序很可能会崩溃,因为没有剩余的 RAM。

看起来像这样的东西:

(dotimes (i 4)
  (profiler-wrapper :messg "After execution memory ~a~%"  (execute-me i) ))

After execution memory +100Mb
After execution memory +100Mb
After execution memory +100Mb
After execution memory +100Mb
NIL
4

2 回答 2

2

试试确定性分析器,它在 Slime 中通过slime-profile*命令或在REPL中可用。它为您进行包装,并且可以报告每个函数的 CPU 和内存使用情况,但会产生一些包装开销。

SBCL 还附带一个统计分析器,它的开销更少,如果需要分析长时间运行的流程并且关于问题区域的先验信息很少或不存在,则它会更有帮助。

于 2012-12-09T07:49:57.693 回答
1

我编写了我自己的这样一个宏的版本,它很可能并不优雅,并且它确实会显着降低代码速度,(sb-ext:gc :full t)但它确实给出了执行给定主体后内存使用的一些观点。

(defparameter *last-profile-step* 0)

(defmacro profile-it ((name gc-on) &body body)
    `(let ((*last-profile-step* ,(if gc-on
                     `(progn
                    (sb-ext:gc :full t)
                    (sb-kernel::dynamic-usage))
                     `(sb-kernel::dynamic-usage))))
       (unwind-protect 
        (progn
          ,@body)
     (progn
       (FORMAT t "After execution of ~a : ~a byte~%" ,name
           (- ,(if gc-on
               `(progn
                  (sb-ext:gc :full t)
                  (sb-kernel::dynamic-usage))
               `(sb-kernel::dynamic-usage))
              *last-profile-step* ))))))
于 2012-12-08T21:41:53.227 回答