Fedora 29(内核 3.15.10-201.fc20.x86_64)这在 F19 中有效。
我正在尝试使用 cgroup 来限制某些容易出现不当行为的应用程序的内存使用,但我遇到了问题。我正在使用一个小型的单一用途程序进行测试。
我的文件中有这个/etc/cgconfig.conf
:
group memtest {
memory {
memory.limit_in_bytes = "209715200";
memory.soft_limit_in_bytes = "104857600";
}
}
这在/etc/cgrules.conf
:
*:memtest memory memtest/
文件memtest.c
大小只有malloc
1GiB,休眠 30 秒,然后释放缓冲区并退出。
当memtest
程序运行时,它的PID正确地列在 中/sys/fs/cgroup/memory/memtest/tasks
,表明它被正确分类。然而,它的内存使用是不是受到限制。
使用ulimit
行为符合预期:
$ (ulimit -S -v 200000 ; ./memtest )
malloc failed: Cannot allocate memory
这是以下的来源memtest.c
:
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
main() {
char *buf;
size_t bytes = (1 * 1<<30);
errno = 0;
buf = malloc(bytes);
if (errno != 0) {
int errno_copy = errno;
perror("malloc failed");
return errno_copy;
}
printf("%d bytes allocated (requested %d)\n",
malloc_usable_size(buf),
bytes);
sleep(30);
printf("Freeing..\n");
free(buf);
return 0;
}
为什么任务被正确分类,但其内存使用不受限制? F19和F20之间发生了什么变化? (我上周才升级到F20。)
谢谢!
答案1
乍一看,我唯一能想到的是 cgconfig.conf 的处理(由系统)的某个地方变得更加严格。与其将限制定义为带引号的字符串,不如删除引号会发生什么。所以像这样:
group memtest {
memory {
memory.limit_in_bytes = 209715200;
memory.soft_limit_in_bytes = 104857600;
}
}
经过深思熟虑,我认为 memory.limit_in_bytes 仅限制物理用户内存,但允许使用交换。您是否需要做的就是将其设置为与以下内容memory.memsw.limit_in_bytes
相同的值:memory.limit_in_bytes
group memtest {
memory {
memory.limit_in_bytes = 209715200;
memory.memsw.limit_in_bytes = 209715200;
memory.soft_limit_in_bytes = 104857600;
}
}
memory.memsw.limit_in_bytes 包括用户内存和交换空间。因此,如果您想要 0 交换空间,则必须设置memory.memsw.limit_in_bytes
等于memory.limit_in_bytes
当您ulimit -S -v 200000
这样做时,会将虚拟内存(交换、共享数据和物理内存)限制为特定数量,因此您的应用程序将没有足够的空间。然而,您的正常系统设置并没有限制交换空间,因此它可能有足够的空间来使用最大用户内存+加上未使用的交换空间。
如果您在进行测试之前关闭交换(并且不使用 ulimit),我预计您的程序将无法分配它请求的内存。