Docker 1.12中-m内存限制是否包含IPC共享内存?求解原因
Docker
-m内存限制是否包含IPC共享内存? 是的,当你使用--ipc host启动容器时,IPC共享内存的使用量会被计入-m设置的内存限制中,这也是你的测试程序被OOMKilled的核心原因,下面详细拆解背后的逻辑:
1. --ipc host的核心影响
添加--ipc host参数后,容器会直接复用宿主机的IPC命名空间,而非创建独立的容器专属IPC空间。这意味着容器内创建的共享内存段确实存在于宿主机的IPC资源池中,但关键在于:这个共享内存的使用者是容器内的进程,而这些进程完全处于Docker通过cgroups设置的内存限制组管控范围内。
2. Docker内存限制的底层机制
Docker的-m(或--memory)参数依赖Linux的cgroups(控制组)memory子系统实现。这个限制会管控该容器所有进程能使用的总内存范围,涵盖的内存类型包括:
- 进程自身的私有内存(比如堆、栈、代码段等)
- 进程挂载并实际使用的共享内存段(不管这个共享内存属于哪个IPC命名空间,只要是该进程组在使用,就会被纳入内存统计)
3. 你的测试场景触发OOM的具体原因
你设置了-m 100m,意味着容器内所有进程的内存使用总和不能超过100MB。当你的测试程序不断向共享内存写入数据时,这些数据会被cgroups实时统计到容器的内存使用量中。当累计写入量超过100MB阈值时,cgroups的内存回收机制会触发OOM Killer,终止你的程序来强制释放内存资源。
即使不使用--ipc host(容器使用独立IPC命名空间),情况也是类似的:容器内的共享内存依然会被计入-m的限制,因为它本质上是容器进程在使用的内存资源。--ipc host只是让宿主机其他进程也能访问这个共享内存,但内存的归属统计始终跟着实际使用它的容器进程走。
你的测试启动命令
docker run -idt -m 100m --ipc host --name ipc_test centos:7 bash
测试程序代码
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <error.h> #include <unistd.h> #include <iostream> #define SIZE 1024*1024*1024 using namespace std; int main() { int shmid ; char *shmaddr ; struct shmid_ds buf ; int flag = 0 ; int pid ; shmid = shmget(15672000, SIZE, IPC_CREAT ) ; if ( shmid < 0 ) { cout << "get shm ipcid failed" << endl; return -1; } cout << "shmid: " << shmid << endl; shmaddr = (char *)shmat( shmid, NULL, 0 ) ; cout << "shmaddr:" << &shmaddr << endl; string a = ""; string b = "1231231231"; // 10 int c = 0; for(int j = 0; j< 10; j++) { cout << j << endl; for(int i = 0; i < 1024*1024; i++) { a += b; } strcpy( shmaddr, a.c_str()); shmaddr += a.length(); c += a.length(); cout << a.length() << endl; a.clear(); } shmdt( shmaddr ) ; return 0 ; }
内容的提问来源于stack exchange,提问作者edwardramsey
相关产品推荐
相关产品推荐

