ulimit 命令详解
更新时间:2026-09-17。「一个命令一个文档」系列,
ulimit属于进程与系统族。高并发服务最常撞上的Too many open files(EMFILE)就是它的-n限制。
ulimit 是 shell 内建命令,控制当前 shell 及其派生子进程的各类资源上限,底层是 getrlimit/setrlimit。
一、查看
bash
ulimit -a # 列出所有限制(软限制)
ulimit -aS # 软限制(soft):当前生效值,进程可自行上调,最高到硬限制
ulimit -aH # 硬限制(hard):上限,非 root 只能下调不能上调| 选项 | 资源 | 典型默认 | 说明 |
|---|---|---|---|
-n | 打开文件描述符数 nofile | 1024 | 高并发头号要调,每连接/每文件占一个 fd |
-u | 最大进程/线程数 nproc | 数千~数万 | 线程多时撞 unable to create new native thread |
-s | 栈大小 KB | 8192(8MB) | 协程/多线程常调小,如 ulimit -s 1024 |
-c | core 文件大小 blocks | 0 | 0=不生成 core;调试崩溃时设 ulimit -c unlimited |
-t | CPU 时间秒 | unlimited | 超时发 SIGXCPU |
-v | 虚拟内存 KB | unlimited | 部分系统用于限内存 |
-l | 可锁内存 KB | 64 | DPDK/大页需调大(memlock) |
二、临时与永久
bash
ulimit -n 65536 # 仅当前 shell 会话生效(先调软,不超硬即可)
ulimit -Hn 1048576 # 需 root,调硬限制
ulimit -n unlimited # 设为无穷(实际受内核 fs.nr_open 约束)/etc/security/limits.conf(及limits.d/):PAM 登录会话永久配置:bash* soft nofile 65536 * hard nofile 1048576- systemd 服务不读 limits.conf(不走登录 PAM),要在 unit 里设:ini改后
[Service] LimitNOFILE=1048576 LimitNPROC=65536systemctl daemon-reload && systemctl restart svc,cat /proc/<pid>/limits验证。 - 容器:
docker run --ulimit nofile=...或 K8s 由运行时/节点配置决定。
三、排查 Too many open files
bash
cat /proc/<pid>/limits | grep -i 'open files' # 该进程实际限制
ls /proc/<pid>/fd | wc -l # 当前打开 fd 数
ls -l /proc/<pid>/fd | awk '{print $NF}' | sort | uniq -c | sort -rn | head
# 看 fd 都花在哪:socket 多=连接泄漏,普通文件多=文件没关
cat /proc/sys/fs/file-max # 系统级总上限
cat /proc/sys/fs/nr_open # 单进程硬顶注意三层上限:进程 nofile ≤ 内核
fs.nr_open(单进程)≤fs.file-max(系统总量)。把 nofile 调到超过 nr_open 会导致该用户无法登录(连登录所需几个 fd 都申请不到),常见翻车点。
四、软限制与硬限制
- 普通进程可在硬限制以内自由调高软限制;硬限制非 root 只能往下调。
- 应用实际拿到的是软限制。
ulimit -n 65536只改了 soft;若 hard 是 4096 会报cannot modify limit: Operation not permitted。
相关命令
运行时改限制见 prlimit(无需重启进程、可改别的 PID),实时 fd/连接用 lsof/ss,systemd 服务管理用 systemctl。
总结
ulimit 管的是当前 shell 及子进程的资源上限(getrlimit/setrlimit):ulimit -a 看全部、-n 文件描述符(高并发必调,治 Too many open files)、-u 线程数、-s 栈、-c core;分软限制(生效值,可在硬限制内自调)与硬限制(非 root 只能降),永久生效登录会话写 limits.conf、systemd 服务用 LimitNOFILE,并受 nr_open/file-max 三层上限约束,运行时改别进程用 prlimit。