如何限制单个Linux进程的内存使用量而不杀死该进程。

4

如何限制单个Linux进程的内存使用量而不杀死该进程。

我知道ulimit可以限制内存使用量,但如果超过限制,将会杀死该进程。

是否有其他命令或Shell可以限制内存使用量并且不杀死该进程?


1
这不正确。在这种情况下,malloc()(在C应用程序中)只是简单地返回NULL,您的进程不会被终止。它可能是因为尝试对NULL指针执行某些操作而被终止。http://linux.die.net/man/3/malloc -- 在错误情况下,这些函数返回NULL。 - user184968
2个回答

7
除了可以使用setrlimit和ulimit工具设置之外,另一种设置限制内存的方法是使用Linux控制组,因为它能够区分进程(或一组进程)对物理内存和虚拟内存的分配。例如,

$ cgcreate -g memory:/myGroup
$ echo $(( 500 * 1024 * 1024 )) > /sys/fs/cgroup/memory/myGroup/memory.limit_in_bytes
$ echo $(( 5000 * 1024 * 1024 )) > /sys/fs/cgroup/memory/myGroupmemory.memsw.limit_in_bytes

将创建名为“myGroup”的控制组,并将运行在该组下的进程的物理内存限制为500 MB,交换空间限制为5000 MB。要在控制组下运行一个进程,可以使用:

$ cgexec -g memory:myGroup COMMAND

注意:据我所知,setrlimit将限制虚拟内存,但使用cgroups可以限制物理内存。

有趣,但我猜如果资源耗尽,进程仍然会被终止。 - Basile Starynkevitch

4

我认为你对使用setrlimit(2)设置限制集会导致进程被杀死的想法是错误的。

事实上,如果超出了堆栈空间(RLIMIT_STACK),则进程将被杀死(使用SIGSEGV)。

但是如果是堆内存(RLIMIT_DATARLIMIT_AS),则mmap(2)会失败。如果它是从malloc(3)或类似函数中调用的,则malloc会失败。

一些Linux系统配置了内存超额分配
这是一个系统管理员问题:echo 0 > /proc/sys/vm/overcommit_memory

故事的寓意是你应该始终检查malloc的结果,至少像这样:

struct mystruct_st *ptr = malloc(sizeof(struct mystruct_st));
if (!ptr) { perror("mystruct allocation"); exit(EXIT_FAILURE); }

当然,复杂的应用程序可能会更明智地处理“内存不足”条件,但要做到这一点很困难。
有些人错误地认为malloc不会失败(这是错误的)。但这是他们的错误。然后他们引用了一个NULL指针,得到了一个他们应该得到的SIGSEGV错误。
您可以考虑使用一些特定于处理器的代码捕获SIGSEGV,请查看此答案。除非您是专家,否则切勿这样做。

从用户的角度来看,当“malloc”返回“NULL”时退出与崩溃几乎没有区别。我相信大多数程序不会崩溃,只是在“malloc”失败后立即退出。 - el.pescado - нет войне
我不同意,perror 给出了一个错误消息,这是用户能够理解的区别。顺便说一下,复杂的应用程序可能会以更明智的方式处理 malloc 失败... - Basile Starynkevitch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接