机器配置

ubuntu 12.04

内核版本:3.11.0-20-generic

ulimit的限制效果

  1. ulimit -m 8192 当内存突破8M时,什么事情都没有发生。直到38M都没任何反应。

  2. ulimit -v 65536 python抛出MemoryError

cgroup的限制效果

  1. echo 8388608 > memory.limit_in_bytes

大小不对,cgroup的内存量计算方法和ps/status不一致。因此限制计数需要根据具体情况调整。

内核计数

/proc/[pid]/statm

size       (1) total program size
(same as VmSize in /proc/[pid]/status)
resident   (2) resident set size
(same as VmRSS in /proc/[pid]/status)
share      (3) shared pages (i.e., backed by a file)
text       (4) text (code)
lib        (5) library (unused in Linux 2.6)
data       (6) data + stack
dt         (7) dirty pages (unused in Linux 2.6)

/proc/[pid]/status

statm的size和resident分别乘以pagesize等于VmSize和VmRSS。

pmap

pmap -p [pid]

可以看到某个进程内部,用户地址空间分配情况。

pmap -d [pid] | grep 'rw' | awk '{a += $2} END {print a}'

可以看到所有可写入的内存大小,应当正好等于正常显示的writeable/private。

这个值,应当等于status的VmHWM+VmStk。不知为何,VmStk和pmap里面显示的stack正好差了一个4k。怀疑是关于目前在正在使用的页的计算差异。

而high water mark,从分析上说,即是某个进程内部,不是stack的,所有可写的地址空间。当然,这些页并不一定立刻映射了物理内存。因此VmHWM > VmRSS应当没什么问题。

ps

ps和top都是读的status,不废话。

资源限制实践

准备

安装cgroup-bin

aptitude install cgroup-bin

setup cgroup-bin

修改/etc/cgconfig.conf:

mount {
        cpu = /sys/fs/cgroup/cpu;
        cpuacct = /sys/fs/cgroup/cpuacct;
        devices = /sys/fs/cgroup/devices;
        memory = /sys/fs/cgroup/memory;
        freezer = /sys/fs/cgroup/freezer;
}

group memimage {
        perm {
                admin {
                        gid = root;
                }
                task {
                        uid = user;
                }
        }
        memory {
                memory.swappiness = 0;
                memory.limit_in_bytes = 2048000000;
        }
}

限定内存用量2G。

service cgconfig start

执行效果

头部加入nice -n 19 cgexec -g memory:memimage

注意:使用内存限制,务必配置OOM日志告警通知。当重启时,管理者必须知道。当重复发生时,必须重新考虑内存限制问题。

监测

查看group内存状态

watch cat /sys/fs/cgroup/memory/memimage/memory.stat