寻找“太多文件”的原因

时间:2010-11-16 11:35:46

标签: java linux sockets

我们在其中一个客户服务器上遇到了一个奇怪的问题,Java遇到“文件过多”,

通过lsof检查描述符会产生一个包含“无法识别协议”的大量“sock”描述符。

我怀疑这是因为套接字打开了太多时间,但由于我们的线程转储包含很多,我不清楚究竟是谁的罪魁祸首。

有没有什么好方法可以检测哪些线程正好打开这些套接字?

感谢。

5 个答案:

答案 0 :(得分:2)

开始

netstat -ano | grep $YOUR_PROCESS_ID - 适用于unix

netstat -ano | find "$YOUR_PROCESS_ID" - 适用于Windows

至少你会看到连接是否真的存在。

答案 1 :(得分:2)

  

有没有什么好方法可以检测哪些线程正好打开这些套接字?

不是线程本身

一种方法是使用分析器运行应用程序。即使您无法准确再现客户的问题,也很容易发现问题。 (@SyBer报告YourKit探查器具有特定支持以查找套接字泄漏...请参阅注释。)

第二种方法是使用ulimit来调整您的测试平台,以减少允许的打开文件数。这可以使您更容易在测试环境中重现“打开太多文件”场景。

最后,我建议“grepping”你的代码库,找到创建套接字对象的所有地方。然后检查它们以确保它们正确使用try / finally块以确保套接字始终关闭。

答案 2 :(得分:1)

您是否尝试ulimit增加打开文件的数量?此外,您可能没有正确关闭插座,因此您有泄漏。

答案 3 :(得分:0)

检测泄漏套接字的唯一“好”方法是非常详细的日志或分析器。进行内存转储并分析对象。

答案 4 :(得分:0)

如果您通过Valgrind

--track-fds=yes将识别文件描述符泄漏。 Valgrind在其跟踪的资源的“获取”点生成短堆栈跟踪。当您找到泄漏源的源线时,您可以将其与pthread_self的返回值结合到您的日志记录系统(我确定您将使用它!),或将breakpoints放在gdb中。

可能你忽略了你完成的close()个套接字。即使对等体启动关闭,也需要这样做。