应对Common Lisp(SBCL)中的内存使用并将其最小化

时间:2009-04-02 08:52:16

标签: memory lisp common-lisp out-of-memory sbcl

我有一个没有太多内存(256Mb)的VPS,我正在尝试使用SBCL + Hunchentoot进行Common Lisp开发来编写一些简单的Web应用程序。大量的内存似乎在没有做任何特别复杂的事情的情况下被使用,并且在服务页面一段时间后,内存耗尽并且使用所有交换变得疯狂或者(如果没有交换)就会死掉。

所以我需要帮助:

  • 找出使用所有内存的内容(如果是库或我,尤其是)
  • 限制允许SBCL使用的内存量,以避免大量交换
  • 在内存耗尽时干净利落地处理事情,而不是崩溃(因为它是一个网络应用程序,我希望它继续并尝试清理)。

我认为前两个是相当简单的,但第三个甚至可能吗? 人们如何处理Lisp中的内存不足或受限的内存条件?

(另外,我注意到64位SBCL似乎使​​用的内存是32位的两倍。这是预期的吗?我可以运行32位版本,如果它会节省大量内存)

4 个答案:

答案 0 :(得分:13)

要限制SBCL的内存使用量,请使用--dynamic-space-size选项(例如,sbcl --dynamic-space-size 128将内存使用量限制为128M)。

要找出谁正在使用内存,你可以在不同的时间调用(room)(这个函数说明正在使用多少内存):在启动时,在加载所有库之后,然后在工作期间(cource) ,在房间之前调用(sb-ext:gc :full t)不要测量尚未收集的垃圾。

此外,可以使用SBCL Profiler来测量内存分配。

答案 1 :(得分:4)

  

找出使用所有内存的内容   (如果是图书馆或我,特别是)

Attila Lendvai有一些特定于SBCL的代码,可以找出分配对象的来源。如果需要,请参阅http://article.gmane.org/gmane.lisp.steel-bank.devel/12903并写一封私人邮件。

请务必尝试其他实现,最好使用精确的GC(如Clozure CL),以确保它不是特定于实现的泄漏。

  

限制SBCL的内存量   允许使用,以避免大规模   交换数量

其他人已经回答了。

  

内存运行时干净利落地处理事情   出来,而不是崩溃(因为它是   我想要它继续的网络应用程序   试着清理)。

256MB很紧,但无论如何:安排一个定期(可能是1s)定时线程来检查剩余的可用空间。如果可用空间小于X,则使用exec()将当前SBCL过程映像替换为新映射。

答案 2 :(得分:3)

如果你没有任何类型声明,我希望64位Lisp占用32位空间的两倍。即使是普通(小)int也会使用64位内存。我不认为它会使用少于一个机器字,除非你声明它。

我无法帮助#2和#3,但如果你弄清楚#1,我怀疑它不会有问题。我已经看到SBCL / Hunchentoot实例运行了很长时间。如果我使用了大量的内存,那通常是我自己的错。 : - )

答案 3 :(得分:1)

我不会对64位SBCL使用两倍的meory感到惊讶,因为它可能会使用64位单元而不是32位单元,但在没有实际检查的情况下无法确定。

让内存闲置的时间长于预期的典型事物是不再有用的引用,它们仍然具有到根分配集的路径(哈希表,我发现,这是让这些东西逗留的好方法)。您可以尝试在代码中散布对GC的显式调用,并确保(尽可能)不将内容存储在全局变量中。

相关问题