这个问题之前困扰了许久,在网上查询了需求也没找到原因,后来在公司博客上看到大佬写的文章,记录在册,以后可用优化后的命令查看打开文件数量。当然也可以直接通过
cat /proc/pid/maps | wc -l 查看进程打开的文件句柄
关于以下两个命令查询出来结果不一样分析
lsof -n | awk ‘{print $2}’ | sort | uniq -c | sort -nr | more
lsof -p PID | wc -l
原因分析
1: lsof 的输出会产生一个 header,这一行会被计算到ls -p PID中。但是第一句中用了awk来过滤。header 这一行没有$2 == PID,所以,计数上面有差了 1 个。这个不是主要原因。
2: lsof默认会输出线程 ID(TID),但是,ls -p 的时候只输出进程打开的文件,不会有TID。对于线程数多的进程,第一行命令查询会大大扩大打开的文件数。实际上,多线程打开的文件数只要计算一次就成了,并不是不同的线程重复打开。这个是 lsof 输出的问题。
建议改进查询命令
如果生产环境打开文件数过多的问题,可以用如下命令查询系统中 top 10 的打开文件数多的进程。然后,再根据 PID 用lsof查询具体的进程。
建议要用 root 权限来运行,要不查询结果不准。
for pid in /proc/[0-9]*; do p=$(basename $pid); printf "%4d FDs for PID %6d; command=%s\n" $(ls $pid/fd | wc -l) $p "$(ps -p $p -o comm=)"; done | sort -nr | head -10