TreeviewCopyright © aleen42 all right reserved, powered by aleen42
memory
限制cgroup中所有进程所能使用的物理内存总量 限制cgroup中所有进程所能使用的物理内存+交换空间总量 限制cgroup中所有进程所能使用的内核内存总量及其它一些内核资源
cgroup.event_control #用于eventfd的接口
memory.usage_in_bytes #显示当前已用的内存
memory.limit_in_bytes #设置/显示当前限制的内存额度
memory.failcnt #显示内存使用量达到限制值的次数
memory.max_usage_in_bytes #历史内存最大使用量
memory.soft_limit_in_bytes #设置/显示当前限制的内存软额度
memory.stat #显示当前cgroup的内存使用情况
memory.use_hierarchy #设置/显示是否将子cgroup的内存使用情况统计到当前cgroup里面
memory.force_empty #触发系统立即尽可能的回收当前cgroup中可以回收的内存
memory.pressure_level #设置内存压力的通知事件,配合cgroup.event_control一起使用
memory.swappiness #设置和显示当前的swappiness
memory.move_charge_at_immigrate #设置当进程移动到其他cgroup中时,它所占用的内存是否也随着移动过去
memory.oom_control #设置/显示oom controls相关的配置
memory.numa_stat #显示numa相关的内存
测试
# cd /sys/fs/cgroup/memory/test/
# sh -c "echo $$ >> cgroup.procs"
# top
打开一个新的窗口
# cat tasks
1289
1482
# cat memory.limit_in_bytes
9223372036854771712
# cat memory.usage_in_bytes
831488
可以看到使用了831K的内存,现在开始限制它的内存
# sudo sh -c "echo 400K > memory.limit_in_bytes" 如果是-1表示不限制
# free
total used free shared buff/cache available
Mem: 4046420 63532 3836216 8428 146672 3775948
Swap: 4194300 0 4194300
# top
在第二个窗口
# cat memory.limit_in_bytes
409600
# cat memory.usage_in_bytes
389120
# free
total used free shared buff/cache available
Mem: 4046420 63788 3835560 8428 147072 3775468
Swap: 4194300 560 4193740
可以看到内存被限制,只能使用交换分区并且频繁的达到内存限制
# cat memory.failcnt
11211
# cat memory.stat
total_pgpgin 43115
total_pgpgout 43016
total_pgfault 35004
频繁的换进换出
memory.oom_control
这个文件里面包含了一个控制是否为当前cgroup启动OOM-killer的标识。如果写0到这个文件,将启动OOM-killer,当内核无法给进程分配足够的内存时, 将会直接kill掉该进程;如果写1到这个文件,表示不启动OOM-killer,当内核无法给进程分配足够的内存时, 将会暂停该进程直到有空余的内存之后再继续运行;同时,memory.oom_control还包含一个只读的under_oom字段, 用来表示当前是否已经进入oom状态,也即是否有进程被暂停了。
写一个测试程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MB (1024 * 1024)
int main(int argc, char *argv[])
{
char *p;
int i = 0;
while(1) {
p = (char *)malloc(MB);
memset(p, 0, MB);
printf("%dM memory allocated\n", ++i);
sleep(1);
}
return 0;
}
编译测试
# sudo sh -c "echo 5M > memory.limit_in_bytes"
# cat memory.oom_control
oom_kill_disable 0
under_oom 0
# sudo sh -c "echo 0 > memory.swappiness"
第二个窗口
# sudo sh -c "echo $$ >> cgroup.procs"
# gcc ~/mem-allocate.c -o ~/mem-allocate
# ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
Killed
上面的测试必须要关闭交换分区,否则会一直从交换分区申请内存
如果设置
# sudo sh -c "echo 1 >> memory.oom_control"
那么程序会一直hang住
# ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
不会被kill
例二:获取oom event
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/eventfd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
static inline void die(const char *msg)
{
fprintf(stderr, "error: %s: %s(%d)\n", msg, strerror(errno), errno);
exit(EXIT_FAILURE);
}
static inline void usage(void)
{
fprintf(stderr, "usage: oom_eventfd_test <cgroup.event_control> <memory.oom_control>\n");
exit(EXIT_FAILURE);
}
#define BUFSIZE 256
int main(int argc, char *argv[])
{
char buf[BUFSIZE];
int efd, cfd, ofd, rb, wb;
uint64_t u;
if (argc != 3)
usage();
if ((efd = eventfd(0, 0)) == -1)
die("eventfd");
if ((cfd = open(argv[1], O_WRONLY)) == -1)
die("cgroup.event_control");
if ((ofd = open(argv[2], O_RDONLY)) == -1)
die("memory.oom_control");
if ((wb = snprintf(buf, BUFSIZE, "%d %d", efd, ofd)) >= BUFSIZE)
die("buffer too small");
if (write(cfd, buf, wb) == -1)
die("write cgroup.event_control");
if (close(cfd) == -1)
die("close cgroup.event_control");
for (;;) {
if (read(efd, &u, sizeof(uint64_t)) != sizeof(uint64_t))
die("read eventfd");
printf("mem_cgroup oom event received\n");
}
return 0;
}