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

Posted

技术标签:

【中文标题】如何限制单个 Linux 进程的内存使用而不杀死该进程【英文标题】:How Limit memory usage for a single Linux process and not kill the process 【发布时间】:2014-11-11 08:45:58 【问题描述】:

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

是否有任何其他命令或shell可以限制内存使用而不杀死进程?

【问题讨论】:

> but if exceed the limit, will kill the process. 。这是不正确的。在这种情况下 malloc() (在 C 应用程序的情况下)只返回 NULL 并且您的进程不会被杀死。它可能因为试图用 NULL 指针做某事而被杀死。 linux.die.net/man/3/malloc -- 出错时,这些函数返回 NULL。 【参考方案1】:

除了setrlimit之外的另一种方式,可以使用ulimit实用程序设置:

$ ulimit -Sv 500000 # 设置 ~500 mb 限制

是使用Linux's control groups,因为它限制了进程(或进程组)分配的物理内存与虚拟内存不同。例如:

$ 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”的控制组,将在 myGroup 下运行的进程集限制为最多 500 MB 的物理内存和最多 5000 MB 的交换空间。在控制组下运行进程:

$ cgexec -g memory:myGroup 命令

注意:据我所知,setrlimit 会限制虚拟内存,尽管使用 cgroups 你可以限制物理内存。

【讨论】:

有趣,但我猜如果资源耗尽,进程仍然会被杀死。【参考方案2】:

我相信您认为使用setrlimit(2) 设置的限制将始终终止进程是错误的。

确实,如果超出堆栈空间(RLIMIT_STACK),进程将被终止(SIGSEGV)。

但如果是堆内存(RLIMIT_DATARLIMIT_AS),mmap(2) 会失败。如果它是从malloc(3) 或朋友那里调用的,那么malloc 将失败。

一些 Linux 系统配置了memory overcommit。 这是一个系统管理员问题: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,请参阅this answer。除非你是大师,否则不要这样做。

【讨论】:

malloc 返回NULL 时退出从用户的角度来看与崩溃几乎没有什么不同。而且我相信大多数程序不会崩溃,只要malloc失败就退出。 我不同意,perror 给出了一条错误消息,这是用户会理解的差异。顺便说一句,复杂的应用程序可能会以更明智的方式处理 malloc 故障....

以上是关于如何限制单个 Linux 进程的内存使用而不杀死该进程的主要内容,如果未能解决你的问题,请参考以下文章

linux系统内存达多少会杀掉进程

oom killer

如何限制Linux内存的使用

Linux如何查看进程杀死进程启动进程等常用命令

Linux命令之终止进程kill

容器中的JVM资源该如何被安全的限制?