处理并最小化 Common Lisp 中的内存使用 (SBCL)

发布于 2024-07-16 02:01:56 字数 472 浏览 11 评论 0原文

我有一个内存不是太多(256Mb)的 VPS,我尝试使用它通过 SBCL+Hunchentoot 进行 Common Lisp 开发,以编写一些简单的 Web 应用程序。 大量的内存似乎在没有做任何特别复杂的事情的情况下被使用,并且在提供页面一段时间后,它耗尽了内存,要么疯狂地使用所有交换,要么(如果没有交换)就死掉了。

所以我需要帮助:

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

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

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

I have a VPS with not very much memory (256Mb) which I am trying to use for Common Lisp development with SBCL+Hunchentoot to write some simple web-apps. A large amount of memory appears to be getting used without doing anything particularly complex, and after a while of serving pages it runs out of memory and either goes crazy using all swap or (if there is no swap) just dies.

So I need help to:

  • Find out what is using all the memory (if it's libraries or me, especially)
  • Limit the amount of memory which SBCL is allowed to use, to avoid massive quantities of swapping
  • Handle things cleanly when memory runs out, rather than crashing (since it's a web-app I want it to carry on and try to clean up).

I assume the first two are reasonably straightforward, but is the third even possible?
How do people handle out-of-memory or constrained memory conditions in Lisp?

(Also, I note that a 64-bit SBCL appears to use literally twice as much memory as 32-bit. Is this expected? I can run a 32-bit version if it will save a lot of memory)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

落花浅忆 2024-07-23 02:01:56

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

要找出谁在使用内存,您可以在不同时间调用 (room) (该函数告知正在使用多少内存):启动时、加载所有库之后以及工作期间(当然,在 room 之前调用 (sb-ext:gc :full t) 是为了不测量尚未收集的垃圾)。

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

To limit the memory usage of SBCL, use --dynamic-space-size option (e.g.,sbcl --dynamic-space-size 128 will limit memory usage to 128M).

To find out who is using memory, you may call (room) (the function that tells how much memory is being used) at different times: at startup, after all libraries are loaded and then during work (of cource, call (sb-ext:gc :full t) before room not to measure the garbage that has not yet been collected).

Also, it is possible to use SBCL Profiler to measure memory allocation.

对你的占有欲 2024-07-23 02:01:56

找出什么占用了所有内存
(尤其是图书馆或我)

Attila Lendvai 有一些特定于 SBCL 的代码来找出分配的对象来自哪里。 请参阅http://article.gmane.org/gmane.lisp.steel -bank.devel/12903 并在需要时给他写一封私人邮件。

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

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

其他人已经回答了。

内存运行时干净利落地处理事情
出,而不是崩溃(因为它是
一个网络应用程序,我希望它继续运行并且
尝试清理)。

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

Find out what is using all the memory
(if it's libraries or me, especially)

Attila Lendvai has some SBCL-specific code to find out where an allocated objects comes from. Refer to http://article.gmane.org/gmane.lisp.steel-bank.devel/12903 and write him a private mail if needed.

Be sure to try another implementation, preferably with a precise GC (like Clozure CL) to ensure it's not an implementation-specific leak.

Limit the amount of memory which SBCL
is allowed to use, to avoid massive
quantities of swapping

Already answered by others.

Handle things cleanly when memory runs
out, rather than crashing (since it's
a web-app I want it to carry on and
try to clean up).

256MB is tight, but anyway: schedule a recurring (maybe 1s) timed thread that checks the remaining free space. If the free space is less than X then use exec() to replace the current SBCL process image with a new one.

番薯 2024-07-23 02:01:56

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

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

If you don't have any type declarations, I would expect 64-bit Lisp to take twice the space of a 32-bit one. Even a plain (small) int will use a 64-bit chunk of memory. I don't think it'll use less than a machine word, unless you declare it.

I can't help with #2 and #3, but if you figure out #1, I suspect it won't be a problem. I've seen SBCL/Hunchentoot instances running for ages. If I'm using an outrageous amount of memory, it's usually my own fault. :-)

空宴 2024-07-23 02:01:56

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

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

I would not be surprised by a 64-bit SBCL using twice the meory, as it will probably use a 64-bit cell rather than a 32-bit one, but couldn't say for sure without actually checking.

Typical things that keep memory hanging around for longer than expected are no-longer-useful references that still have a path to the root allocation set (hash tables are, I find, a good way of letting these things linger). You could try interspersing explicit calls to GC in your code and make sure to (as far as possible) not store things in global variables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文