系统任务数上限
kernel.threads-max 是整台机器允许存在的任务(线程)总数上限,内核在启动时按物理内存规模自动计算。每创建一个线程都要占用内核栈与调度实体,所以上限与内存挂钩。触顶后 fork/clone 返回 EAGAIN,应用侧看到 fork: Resource temporarily unavailable 或 Cannot allocate memory。它管全机总量,与单用户的 ulimit -u、cgroup 的 pids.max 属于三个不同层次。
基本信息
| 参数名 | kernel.threads-max |
|---|---|
| 默认值 | 启动时按物理内存自动计算,机型间差异大 |
| 查看现状 | ps -eLf | wc -l 统计当前线程总数 |
| 三层限制 | ulimit -u(按用户)→ cgroup pids.max(按组)→ threads-max(全机) |
| 触顶报错 | EAGAIN:fork: Resource temporarily unavailable |
典型使用场景
- 出现 fork 失败时按「用户限额 → cgroup → 全机总量」顺序定位
- 线程池失控或每请求建线程的服务,需要判断是否撞到系统上限
- 容器平台评估单机可承载的 Pod 与线程预算
- 配置基线审计:核对 threads-max 与物理内存是否匹配
- 变更前容量验证:同时核对 ulimit 与 cgroup 两个更早生效的限制
查看与定位
查看与定位
sysctl kernel.threads-max # 全机线程上限
ps -eLf | wc -l # 当前线程总数(L 选项显示线程)
ulimit -u # 当前用户的进程/线程数上限
cat /sys/fs/cgroup/pids.max 2>/dev/null # cgroup v2 的组级上限
cat /sys/fs/cgroup/pids.current 2>/dev/null
ps -eLf | awk '{print $2}' | sort | uniq -c | sort -rn | head -5 # 谁线程最多
sysctl -w kernel.threads-max=200000 # 属临时变更,重启后恢复三层限制对照
| 层次 | 参数或文件 | 影响范围 |
|---|---|---|
| 用户层 | ulimit -u / RLIMIT_NPROC | 同一 uid 下的全部进程与线程 |
| cgroup 层 | pids.max 与 pids.current | 该控制组内的任务,容器场景最常用 |
| 全机层 | kernel.threads-max | 整台机器上的所有任务 |
| 隐含成本 | 内核栈由内存承担 | 线程越多,不可换出的内核内存越多 |
线程数暴涨基本是泄漏信号,常见于每请求建线程、连接池失控、线程池拒绝策略不当;先定位来源再决定是否动上限。
调大 threads-max 只解决「能创建」,不解决内存:每个线程的内核栈不可换出,线程过多会把 OOM 风险显著抬高。