Common lisp 如何使用sbcl隔离内存泄漏/丢失
我的应用程序将给定的数据转换为树表示,它使用的内存太多了。因为它在崩溃之前能够将大约200-300MB的内存转换为大约3GB 我现在想找出漏洞在哪里,是程序的哪个部分导致的 因此,我现在确实想知道,在common lisp中,使用sbcl进行内存分析最常见、最有效的技术是什么 我已经看过了Common lisp 如何使用sbcl隔离内存泄漏/丢失,common-lisp,sbcl,Common Lisp,Sbcl,我的应用程序将给定的数据转换为树表示,它使用的内存太多了。因为它在崩溃之前能够将大约200-300MB的内存转换为大约3GB 我现在想找出漏洞在哪里,是程序的哪个部分导致的 因此,我现在确实想知道,在common lisp中,使用sbcl进行内存分析最常见、最有效的技术是什么 我已经看过了(room)和(time),但是它的输出非常详细,我所需要的只是一个包装器,它会说“在执行之后,总内存使用量为+1000字节”,这将完成交易,因为我只想知道内存在哪里使用。另一个标准是它必须“动态”工作,因为应
(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还附带了一个统计分析器,它的开销更小,如果需要分析长时间运行的流程,并且之前很少或根本没有关于问题区域的信息,它会更有用。这些工具不会即时工作,而且会为了我的目的而冗长。