Common lisp 如何使用sbcl隔离内存泄漏/丢失

Common lisp 如何使用sbcl隔离内存泄漏/丢失,common-lisp,sbcl,Common Lisp,Sbcl,我的应用程序将给定的数据转换为树表示,它使用的内存太多了。因为它在崩溃之前能够将大约200-300MB的内存转换为大约3GB 我现在想找出漏洞在哪里,是程序的哪个部分导致的 因此,我现在确实想知道,在common lisp中,使用sbcl进行内存分析最常见、最有效的技术是什么 我已经看过了(room)和(time),但是它的输出非常详细,我所需要的只是一个包装器,它会说“在执行之后,总内存使用量为+1000字节”,这将完成交易,因为我只想知道内存在哪里使用。另一个标准是它必须“动态”工作,因为应

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

我现在想找出漏洞在哪里,是程序的哪个部分导致的

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

我已经看过了
(room)
(time)
,但是它的输出非常详细,我所需要的只是一个包装器,它会说“在执行之后,总内存使用量为+1000字节”,这将完成交易,因为我只想知道内存在哪里使用。另一个标准是它必须“动态”工作,因为应用程序很可能会崩溃,因为没有剩余的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

我自己编写了这样一个宏的版本,它很可能并不优雅,而且由于
(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* ))))))

尝试deterministic profiler,它可通过或在Slime中获得。它为您进行包装,并可以报告每个函数的CPU和内存使用情况,但要以包装的一些开销为代价


SBCL还附带了一个统计分析器,它的开销更小,如果需要分析长时间运行的流程,并且之前很少或根本没有关于问题区域的信息,它会更有用。

这些工具不会即时工作,而且会为了我的目的而冗长。