一眼确认fd是否在涨:盯住/proc/PID/fd/数量变化,用watch -n 1 'ls /proc/PID/fd/ | wc -l'实时监控,数字持续上升即泄漏;再结合lsof -p PID | grep -E "(socket|anon_inode)"识别异常类型,最后用perf或strace跟踪open/close是否成对。

一眼确认 fd 是否在涨:盯住 /proc/PID/fd/ 数量变化
泄漏不是静态快照,是随时间推移持续增长的过程。单次 lsof -p PID | wc -l 或 ls /proc/PID/fd/ | wc -l 没意义,必须看趋势。
最直接有效的方法是:
- 先执行
ls /proc/PID/fd/ | wc -l记下基线值 - 立刻运行
watch -n 1 'ls /proc/PID/fd/ | wc -l'——watch会高亮变化行,比人眼盯终端省力得多 - 若数字每秒 +1、+2,或出现跳变(如 1024 → 1037),基本可锁定该进程
注意:/proc/PID/fd/ 是内核实时视图,不经过任何抽象层,比 lsof 更轻量、更可靠,尤其在高 fd 场景下不会卡住或丢数据。
快速识别泄漏类型:lsof 输出里哪些行要立刻警惕
lsof -p PID 的输出里,以下模式不是“多开几个文件”的正常现象,而是泄漏强信号:
-
FD列持续出现递增数字(如1024r、1025w、1026u),且NAME指向同一类路径(如/tmp/log_*.txt、/var/log/app/*.log) -
TYPE=REG且NAME含(deleted)—— 文件已被unlink,但进程还握着句柄,磁盘空间不释放 -
TYPE=anon_inode大量出现,尤其是重复显示anon_inode:[eventpoll]或anon_inode:[timerfd]—— epoll、定时器、eventfd 未close -
TYPE=sock+STATE=ESTABLISHED,但业务并发量远低于 socket 数(如只有 5 个 HTTP 请求,却有 200+ ESTABLISHED) -
NAME为空,或为socket:[1234567]—— 这类需配合ls -l /proc/PID/fd/ | grep socket查真实符号链接
别依赖默认 lsof:加 -n -P 参数(lsof -n -P -p PID),禁用 DNS 和端口名解析,避免命令自身卡死或输出失真。
定位到具体代码:用 perf 或 strace 跟踪 open/close 是否成对
靠扫代码效率极低,优先用系统调用跟踪确认资源生命周期是否完整:
- CentOS 7.9+ / kernel ≥ 4.1:用
perf trace -e syscalls:sys_enter_openat,syscalls:sys_enter_close -p PID,观察是否有openat后长期不见对应close - 环境不支持 perf:改用
strace -p PID -e trace=open,openat,close,closefrom 2>&1 | grep -E "(open|close)";加-v可见参数(如路径、返回 fd 值) - C/C++ 进程注意
FD_CLOEXEC:fork 后子进程继承父进程 fd 是默认行为,若子进程不操作这些 fd 却没设该 flag,它们就成了“幽灵句柄” - Java 进程别迷信
try-with-resources:若底层用了 JNI 创建socket或epoll,而Cleaner或finalize里没显式close,照样泄漏
特别提醒:strace 在高并发场景下开销大,建议只在复现稳定时短时启用;perf trace 开销小得多,适合线上轻量跟踪。
别被“Too many open files”骗:lsof 看不到的泄漏才最危险
这是最容易踩坑的点:lsof 默认只显示当前打开的句柄,但某些泄漏是“瞬时创建 + 长期持有”,比如:
- 短连接高频调用 REST 接口,
socket创建后未shutdown就直接close,残留CLOSE_WAIT状态(lsof显示TYPE=sock STATE=CLOSE_WAIT) - 异步 I/O 初始化(如
io_uring_register)后未注销,内核对象一直驻留 - 子进程继承了父进程 fd 但没关闭,父进程退出后子进程继续跑,句柄在子进程中“隐身”增长
这类问题往往要结合 /proc/PID/fd/ 符号链接内容、ps -o pid,ppid,tid,comm -T -p PID 查线程树、以及 cat /proc/PID/status | grep -i fdsize 看内核实际分配上限,才能绕过 lsof 的盲区。


















