--memory 和 --memory-swap 的数字怎么算?容器内存超了是被杀,还是被换到 swap?这篇把几种组合翻译成 cgroup 文件里的值,并用逐步分配内存的程序看每种设置下的实际表现。
虚拟机的 /proc/meminfo:MemTotal: 8124516 kB;SwapTotal: 1048572 kB; 不限制:memory.max=max memory.swap.max=max --memory 64m:memory.max=67108864 memory.swap.max=67108864 --memory 64m --memory-swap 64m:memory.max=67108864 memory.swap.max=0 --memory 64m --memory-swap 128m:memory.max=67108864 memory.swap.max=67108864 --memory 64m --memory-swap -1:memory.max=67108864 memory.swap.max=max
虚拟机有约 1 GiB swap。--memory 64m 单独使用时,swap 也被限制在 64 MiB(memory.swap.max = 67108864);--memory-swap 表示内存加 swap 的总和,所以 128m 配 64m 内存,swap 只有 64 MiB;--memory-swap 64m 则完全不允许 swap(0);-1 不限。
不限制:最后一条输出「已分配 200 MiB(memory.current=204 MiB,swap.current=0 MiB)」;ExitCode=0 OOMKilled=False --memory 64m:最后一条输出「已分配 110 MiB(memory.current=54 MiB,swap.current=61 MiB)」;ExitCode=137 OOMKilled=True --memory 64m --memory-swap 64m:最后一条输出「已分配 50 MiB(memory.current=54 MiB,swap.current=0 MiB)」;ExitCode=137 OOMKilled=True --memory 64m --memory-swap 128m:最后一条输出「已分配 110 MiB(memory.current=54 MiB,swap.current=64 MiB)」;ExitCode=137 OOMKilled=True --memory 64m --memory-swap -1:最后一条输出「已分配 200 MiB(memory.current=54 MiB,swap.current=151 MiB)」;ExitCode=0 OOMKilled=False
分配 200 MiB:不允许 swap 的容器在 50 MiB 附近就被杀(137,OOMKilled=true);允许 64 MiB swap 的撑到 110 MiB(约 54 MiB 在内存、60 MiB 左右在 swap);swap 不限的把 200 MiB 都分配了,其中 151 MiB 被换到 swap,容器没被杀——代价是换页的开销,我没有测速度。
memory.high / memory.low 等:high=max low=33554432 max=67108864 docker stats --no-stream:552KiB / 64MiB 占 0.84%
--memory-reservation 对应 memory.low(32 MiB),docker stats 的 LIMIT 仍是 --memory 的 64MiB。memory.low 在内存紧张时才起作用,怎么起作用我没有实验。