应直接读取/proc/sys/kernel/shmmax和shmall获取内核实际生效值;临时调整用sysctl -w,永久生效需修改/etc/sysctl.conf并执行sysctl -p;shmmax建议≤物理内存一半,shmall单位为页且须≥ceil(shmmax/pagesize)。

查当前 shmmax 和 shmall 值,别凭经验猜
直接看内核实际生效值,不是看配置文件里写了什么:cat /proc/sys/kernel/shmmax 和 cat /proc/sys/kernel/shmall。这两个文件反映的是当前运行时的真实限制。很多问题不是设得不对,而是压根没生效——比如改了 /etc/sysctl.conf 却忘了 sysctl -p,或者写错了参数名(shm_max 或 kernel.shmmaxx 都不会报错,但静默失败)。
临时调大:验证用,不重启立即生效
用 sysctl -w 最安全,它会做基础校验;直接写 /proc 也行,但要 root 权限:
- 设单段最大为 2GB:
sudo sysctl -w kernel.shmmax=2147483648 - 设总页数为 524288 页(假设页面大小是 4096 字节,即 2GB):
sudo sysctl -w kernel.shmall=524288 - 或绕过 sysctl:
echo 2147483648 | sudo tee /proc/sys/kernel/shmmax
注意:shmall 单位是“页”,不是字节;必须 ≥ ceil(shmmax / getconf PAGESIZE),否则 shmget 可能成功,但 shmat 时触发 OOM killer。
永久生效:只写 conf 不够,还得 reload
编辑 /etc/sysctl.conf,追加两行(不要拼错参数名,不要漏空格):
kernel.shmmax = 2147483648 kernel.shmall = 524288
保存后必须执行:sudo sysctl -p。这步不能跳过——systemd 下 /etc/rc.local 已基本失效,依赖它等于没配。验证是否加载成功:sysctl kernel.shmmax kernel.shmall,输出应和 conf 里一致。
设多大才算合理?物理内存和页面对齐是硬约束
不是越大越好,三重现实限制卡得死:
-
shmmax不建议超过物理内存一半(官方建议),否则可能挤占其他进程可用内存 -
shmall过大但物理内存不足时,shmget成功,shmat时才真正分配,容易被 OOM killer 干掉 - 老内核(如 2.6.32)对
shmmax有隐式上限(常见 4GB),设更高会被截断,务必用cat /proc/sys/kernel/shmmax确认最终值 - Oracle 类应用要求
shmmax ≥ SGA_TARGET,但还要预留至少 10% 给系统缓存和页表管理
真正出问题的地方,往往不是不会改,而是改完没验证是否被内核真正接受,或者忽略了 shmall 必须按页面大小换算——shmmax 设对了,shmall 没对齐,照样启动失败。











