Linux中调整共享内存限制需正确配置kernel.shmmax(单段最大字节数)和kernel.shmall(系统总页数),二者必须严格匹配;查实际值应读/proc/sys/kernel/shmmax与shmall,临时调用sysctl -w,永久生效须修改/etc/sysctl.conf并执行sysctl -p,且shmall≥ceil(shmmax/PAGESIZE)。

Linux 中调整进程间通信的共享内存最大限制,核心是正确配置两个内核参数:kernel.shmmax(单段最大字节数)和kernel.shmall(系统总共享内存页数),二者必须严格匹配,缺一不可。
查当前实际生效值
别信配置文件或文档,直接读内核运行时值:
- cat /proc/sys/kernel/shmmax —— 单段最大字节数(如 33554432 = 32MB)
- cat /proc/sys/kernel/shmall —— 总页数(不是字节!)
- getconf PAGESIZE —— 确认当前页面大小(x86_64 通常是 4096,ARM 或大页环境可能为 65536)
很多问题根源是改了但没生效——比如只改了 /etc/sysctl.conf 却忘了 sysctl -p,或参数名拼错(如 shm_max)导致静默失败。
临时调整(立即生效,重启丢失)
适合快速验证或调试,推荐用 sysctl -w(带基础校验,比直接写 /proc 更安全):
- 设单段最大为 2GB:
sudo sysctl -w kernel.shmmax=2147483648 - 对应页数(假设页面为 4096 字节):
sudo sysctl -w kernel.shmall=524288
注意:shmall 必须 ≥ ceil(shmmax / PAGESIZE)。若只调 shmmax 而 shmall 不足,shmget 可能成功,但首次 shmat 时内核发现页数超限,会触发 OOM killer 杀掉进程。
永久生效(重启后仍有效)
两步缺一不可:
- 编辑
/etc/sysctl.conf,追加两行(等号前后保留空格):kernel.shmmax = 2147483648kernel.shmall = 524288 - 执行:
sudo sysctl -p—— 这步必须做,否则配置不加载
验证是否生效:sysctl kernel.shmmax kernel.shmall,输出应与 conf 文件一致。避免使用 /etc/rc.local,systemd 下基本不执行。
设多大才合理
不是越大越好,三重硬约束要兼顾:
-
shmmax建议 ≤ 物理内存一半(官方建议),防止挤占其他进程可用内存 -
shmall过大会占用大量页表空间,反而降低整体内存可用性 - 老内核(如 2.6.32)对
shmmax有隐式上限(常见 4GB),设更高会被截断,务必用/proc确认最终值 - Oracle 等应用要求
shmmax ≥ SGA_TARGET,但还需预留至少 10% 给系统缓存和页表管理
真正出问题的地方,往往不是不会改,而是改完没验证是否被内核真正接受,或者忽略了 shmall 必须按页面大小换算对齐。


















