ulimit 是什么
ulimit 是 shell 内建命令,读写的是当前进程的 setrlimit 资源限制。它决定单个进程能打开多少文件描述符(nofile)、能写多大的 core 文件、栈有多大等。服务报 Too many open files、core 文件生成为空、程序无法创建新线程,绝大多数都要回到这里逐层核对:单元配置、limits.conf、当前会话的实际值。
基本信息
| 适用平台 | Linux/Unix(bash 内建,底层是 setrlimit 系统调用) |
|---|---|
| 命令语法 | ulimit [-a] [-n 值] [-c 值] ...,-S 改软限,-H 改硬限 |
| 常用参数 | -n 打开文件数 -c core 文件大小 -u 进程数 -s 栈大小 -v 虚拟内存 -f 单文件大小 -a 显示全部 |
| 关键区别 | 软限是当前生效值,硬限是能提升到的上限;提高硬限需要 root |
| 影响范围 | 只作用于当前 shell 及其后续子进程,对已运行的服务无效 |
典型使用场景
- 报 Too many open files:确认应用进程实际的 nofile 值与配置是否一致
- 排查崩溃取证:确认 core 大小不是 0,且 core_pattern 指向可写路径
- 高并发服务调优:把 nofile 提到几万,并评估对应的内存开销
- 线程创建失败:进程数限制与 nofile 限制都可能,两者都要看
- 排查「配了却不生效」:区分登录会话限制、systemd 服务限制与容器限制三条路径
常用示例
常用示例
ulimit -a # 查看当前会话的全部限制
ulimit -Hn ; ulimit -Sn # 分别看硬限与软限的 nofile
ulimit -n 65535 # 当前会话临时提高,不能超过硬限
ulimit -c unlimited # 允许生成 core 文件
cat /proc/sys/kernel/core_pattern # 查看 core 落盘位置
cat /proc/1234/limits # 看某个已运行进程的实际上限
prlimit --pid 1234 # 列出或在线调整指定进程的资源限制持久化配置
持久化配置
# /etc/security/limits.conf(仅对经 PAM 登录的会话生效)
appuser soft nofile 65535
appuser hard nofile 65535
# systemd 服务不读 limits.conf,要写在单元里
# /etc/systemd/system/myapp.service
[Service]
LimitNOFILE=65535常用参数读法
| 参数 | 限制的是什么 | 常见取值 |
|---|---|---|
| -n | 同时打开的文件描述符数 | 普通服务 65535 起,高并发再往上 |
| -c | core 文件最大大小 | 0 表示不生成,排障时设 unlimited |
| -u | 单用户可运行的进程或线程数 | 并发线程多的服务需要同步上调 |
| -s | 栈大小(KB) | 默认常见 8192,深递归程序可临时调大 |
| -v | 虚拟内存(KB) | 设限过小会让大内存程序直接启动失败 |
| -H 与 -S | 硬限与软限 | 软限只能升到硬限以内 |
systemd 管理的服务不读 limits.conf:必须在单元里写 LimitNOFILE=、LimitCORE= 等,改完先 daemon-reload 再重启服务。混淆这两条路径是「明明改了配置却没生效」的最常见原因。
limits.conf 里的通配行星号不作用于 root,root 需要单独写一行;并且它只影响通过 PAM 登录的会话(ssh、su、login),systemd 服务、cron 与容器里的进程要各自确认。