当我们的应用程序运行一段时间后,例如,运行几个小时,sbcl将抛出堆耗尽异常。
Heap exhausted during garbage collection: 1968 bytes available, 2128 requested.
Gen StaPg UbSta LaSta LUbSt Boxed Unboxed LB LUB !move Alloc Waste Trig WP GCs Mem-age
0: 0 0 0 0 0 0 0 0 0 0 0 5368709 0 0 0.0000
1: 0 0 0 0 0 0 0 0 0 0 0 5368709 0 0 0.0000
2: 0 0 0 0 0 0 0 0 0 0 0 5368709 0 0 0.0000
3: 101912 101913 0 0 19362 20536 0 0 0 162867456 554752 102714709 0 1 1.4405
4: 130984 131071 0 0 29240 18868 0 0 25 191196152 5854216 128537781 14785 1 0.6442
5: 75511 81013 0 0 16567 17127 92 99 36 132974568 5818392 2000000 16565 0 0.0000
6: 0 0 0 0 7949 1232 0 0 0 37605376 0 2000000 7766 0 0.0000
Total bytes allocated = 524643552
Dynamic-space-size bytes = 536870912
GC control variables:
*GC-INHIBIT* = true
*GC-PENDING* = true
*STOP-FOR-GC-PENDING* = false
fatal error encountered in SBCL pid 3281(tid 3067845440):
Heap exhausted, game over.
Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb>
有什么建议吗?
答案 0 :(得分:1)
SBCL不允许您在堆上分配超过(sb-ext:dynamic-space-size)
个字节。这里有一个512MB的默认大小(536870912字节),并且当它试图进行另一次分配时,Lisp程序已经使用了几乎这个数量。
通过使用--dynamic-space-size 1024启动SBCL,可以将可用的堆空间量增加一倍。然而,正如几条评论指出的那样,可能存在内存泄漏,其中对象的引用与某种程度上成比例系统运行的时间,这只会暂时缓解。
(room t)
标准Common Lisp函数调用可能有助于调试此问题,如果您定期调用它。
像http://dwim.hu/darcsweb/darcsweb.cgi?r=HEAD%20hu.dwim.debug;a=headblob;f=/source/path-to-root.lisp#l42这样深入研究SB-VM内部分配图的更高级代码可以提供更多亮点,而SBCL也有一个统计分析器http://www.sbcl.org/manual/#Statistical-Profiler,它也支持报告分配。