如何追踪文件描述符泄漏?

我有一个java进程(Glassfish),这是泄漏文件描述符。 我知道这是因为我得到了有用的java.io.IOException: Too many open filesexception。 我可以查看/proc/PID#/fd并查看所有打开的文件描述符。 当我使用lsof时,我得到了很多这样的条目:

java 18510 root 8811u sock 0,4 1576079无法识别协议
java 18510 root 8812u sock 0,4 1576111无法识别协议
java 18510 root 8813u sock 0,4 1576150无法识别协议

我看到每分钟创build12个新的。 我可以在lsof上使用哪些选项,或者有什么其他工具可以帮助我追踪无法识别协议的套接字文件描述符?

使用进程查看前20个文件句柄:

 for x in `ps -eF| awk '{ print $2 }'`;do echo `ls /proc/$x/fd 2> /dev/null | wc -l` $x `cat /proc/$x/cmdline 2> /dev/null`;done | sort -n -r | head -n 20 

输出格式为文件句柄计数,pid,cmndline为进程

示例输出

 701 1216 /sbin/rsyslogd-n-c5 169 11835 postgres: spaceuser spaceschema [local] idle 164 13621 postgres: spaceuser spaceschema [local] idle 161 13622 postgres: spaceuser spaceschema [local] idle 161 13618 postgres: spaceuser spaceschema [local] idle 

熟悉strace命令。 它监视系统调用。 我最近使用它来追踪导致我们的snmpd守护进程重复崩溃的文件描述符泄漏。 它需要一些习惯,但它是一个强大的工具。

您可以使用strace附加到正在运行的进程(不要忘记-f标志来关注subprocess)。

你到底在想什么? 与泄漏的FD相关的远程IP地址,有缺陷的代码或其他东西?

由于您已经确定存在泄漏,请联系负责此Javastream程的工程师似乎是合理的下一步。