如何限制单个 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_DATA
或 RLIMIT_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 进程的内存使用而不杀死该进程的主要内容,如果未能解决你的问题,请参考以下文章