Linux系统最大进程数由ulimit -u、pid_max、threads-max三层限制共同决定,最小值即真实上限;需同步配置limits.conf、systemd服务LimitNPROC及sysctl.d中pid_max/threads-max参数,并重载验证。

Linux 服务器上调整系统最大进程数限制,不是改一个参数就能生效的事。它由三层独立但相互制约的限制共同决定:用户级(ulimit -u)、系统级 PID 池上限(/proc/sys/kernel/pid_max)、内核总线程容量(/proc/sys/kernel/threads-max)。三者中最小的那个值,就是你实际能用的上限。漏掉任何一层,高并发服务(如 Java 应用、Nginx、Redis)仍会报 fork: Cannot allocate memory 或 java.lang.OutOfMemoryError: unable to create new native thread。
查清当前卡在哪一层
别猜,直接查三个关键值:
当前用户能开多少进程/线程:
ulimit -u全局最多可分配多少个 PID(即系统级上限):
cat /proc/sys/kernel/pid_max内核允许的总线程数(受内存和 pid_max 共同约束):
cat /proc/sys/kernel/threads-max
再看当前已用线程总数:ps -eLf | wc -l
哪个数值最小,哪个就是真实瓶颈。比如 pid_max=4194304、threads-max=131072,但 ulimit -u=4096,那第 4097 个线程就失败——再大的内核池也没用。
永久调整用户级进程/线程总数(最常见生效点)
Linux 中线程也占用 PID,所以 ulimit -u 同时限制进程 + 线程总数。这是普通服务启动时最先触达的限制。
在 /etc/security/limits.d/90-nproc.conf 中写入:
* soft nproc 65535 * hard nproc 65535 root soft nproc 65535 root hard nproc 65535
确保 PAM 加载该配置:
检查 /etc/pam.d/common-session 和 /etc/pam.d/common-session-noninteractive 是否包含:session required pam_limits.so
普通用户需完全登出重登录(SSH 重连),或执行 su - $USER 触发重载;source 或重启 sshd 无效。
配置 systemd 服务的进程数限制(对 systemctl 启动的服务必须单独设)
/etc/security/limits.conf 对 systemd 服务完全无效。nginx、Java、Spring Boot 等通过 systemctl start 启动的服务,必须显式配置:
-
单服务生效(推荐):
sudo systemctl edit your-service.service
添加:[Service] LimitNPROC=65535
-
全局生效(慎用):
sudo systemctl edit --full systemd-system.conf
加入:DefaultLimitNPROC=65535
改完必须执行:sudo systemctl daemon-reload && sudo systemctl restart your-service
验证是否生效:prlimit -n $(pgrep -f "your-service" | head -1)
同步调大内核级上限(pid_max 和 threads-max)
若用户级已放开,但仍 fork 失败或线程数上不去,说明内核池子不够。
临时设置(验证用):
sudo sysctl -w kernel.pid_max=2097152sudo sysctl -w kernel.threads-max=131072-
永久生效(推荐方式):
新建/etc/sysctl.d/99-pidmax.conf,内容为:kernel.pid_max = 2097152 kernel.threads-max = 131072
执行:
sudo sysctl --system
⚠️ 注意:
-
threads-max不应显著超过pid_max,建议设为pid_max的 60%~80%; - x86_64 架构下
pid_max最高支持4194304,设更高会被静默截断; - 修改后务必运行
cat /proc/sys/kernel/pid_max确认值已更新,否则配置未生效(空格、不可见字符都会导致失败)。
不复杂但容易忽略


















