linux最大进程数由ulimit -u、kernel.pid_max、kernel.threads-max三者最小值决定;需同步调整三层限制,否则无效;systemd服务还需单独配置limitnproc。

Linux 系统中最大进程数(含线程)不是单一参数决定的,而是由 ulimit -u、kernel.pid_max、kernel.threads-max 三层限制共同作用,实际生效值取三者中的最小值。配置时必须同步调整这三项,否则改了也无效。
ulimit -u:用户级进程+线程总数上限(最常卡住你的那层)
这是 Java、Python 多线程服务报 OutOfMemoryError: unable to create new native thread 的首要原因。它不限制“纯线程”,而是把线程当作轻量进程(LWP),一并计入总数。
- 临时生效(仅当前终端及子进程):
ulimit -u 65535
- 永久生效需三步:
- 写入
/etc/security/limits.d/90-nproc.conf(推荐路径,比limits.conf更清晰):* soft nproc 65535 * hard nproc 65535 root soft nproc 65535 root hard nproc 65535
- 确保
/etc/pam.d/common-session包含:session required pam_limits.so
- 用户必须完全登出再重新登录(
su - $USER也可,但source或重启终端无效)
- 写入
注意:systemd 启动的服务(如
systemctl start nginx)完全不读此文件,需单独配LimitNPROC。
kernel.pid_max:系统 PID 编号池上限(fork 失败的直接原因)
当出现 fork: Cannot allocate memory,且 ps -eLf | wc -l 接近或超过 cat /proc/sys/kernel/pid_max 的 70%,就说明 PID 池快耗尽。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 临时修改(重启失效,用于验证):
sudo sysctl -w kernel.pid_max=196608 # 或 echo 196608 | sudo tee /proc/sys/kernel/pid_max
- 永久生效:
- 新建
/etc/sysctl.d/99-pidmax.conf:kernel.pid_max = 196608
- 加载配置:
sudo sysctl --system
- 新建
- 验证必须用:
cat /proc/sys/kernel/pid_max # 不要用 sysctl kernel.pid_max(可能缓存)
x86_64 架构上限为 4194304,设更高会被静默截断。
kernel.threads-max:内核允许的最大线程总数(内存决定的硬上限)
该值由物理内存大小自动计算(mempages / (THREAD_SIZE/PAGE_SIZE) / 8),一般无需手动调高,除非你有超大内存且线程数真逼近它。
- 查看当前值:
cat /proc/sys/kernel/threads-max
- 临时修改(极少需要):
sudo sysctl -w kernel.threads-max=262144
- 永久修改同理写入
/etc/sysctl.d/99-threadsmax.conf并执行sudo sysctl --system。
systemd 服务必须显式配 LimitNPROC
用 systemctl 启动的服务不受 limits.conf 影响。必须在 service 文件中加:
[Service] LimitNPROC=65535 # 或设为 unlimited(慎用) # LimitNPROC=infinity
- 单服务:编辑
/etc/systemd/system/myapp.service - 全局生效(影响所有新启动服务):
# /etc/systemd/system.conf DefaultLimitNPROC=65535
- 修改后务必执行:
sudo systemctl daemon-reload sudo systemctl restart myapp
- 验证是否生效:
systemctl show myapp.service | grep NPROC # 或查具体进程 prlimit -n $(pgrep -f myapp) | grep "MAX"
不复杂但容易忽略










