Java 寻找“;文件太多”;原因

Java 寻找“;文件太多”;原因,java,linux,sockets,Java,Linux,Sockets,我们在一个客户服务器上遇到了一个奇怪的问题,Java遇到了“太多文件” 通过lsof检查描述符会生成一个带有“无法识别协议”的“sock”描述符的大列表 我怀疑这是由于套接字打开时间过长造成的,但由于我们的线程转储中包含了很多套接字,我不清楚到底是谁造成的 有没有什么好的方法来检测哪些线程恰好打开了这些套接字 谢谢。您是否尝试增加打开的文件数量?另外,可能是您没有正确关闭套接字,因此发生了泄漏。检测套接字泄漏的唯一“好”方法是使用非常详细的日志或探查器。执行内存转储并分析对象。从 netstat

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

通过lsof检查描述符会生成一个带有“无法识别协议”的“sock”描述符的大列表

我怀疑这是由于套接字打开时间过长造成的,但由于我们的线程转储中包含了很多套接字,我不清楚到底是谁造成的

有没有什么好的方法来检测哪些线程恰好打开了这些套接字

谢谢。

您是否尝试增加打开的文件数量?另外,可能是您没有正确关闭套接字,因此发生了泄漏。

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

netstat-ano | grep$您的进程ID
-用于unix

netstat-ano |为windows查找“$YOUR_PROCESS_ID”

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

有没有什么好的方法来检测哪些线程恰好打开了这些套接字

而不是线程本身


一种方法是使用探查器运行应用程序。即使您无法准确再现客户的问题,这也很可能发现问题。(@SyBer报告YourKit探查器对查找套接字泄漏具有特定支持…请参阅评论。)

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

最后,我建议对代码库进行“grepping”,以查找创建套接字对象的所有位置。然后检查它们,确保它们正确使用try/finally块,以确保套接字始终处于关闭状态。

如果通过,将识别文件描述符泄漏。Valgrind在其跟踪的资源的“采集”点生成短堆栈跟踪。找到发生泄漏的源线后,可以将其与到日志系统的返回值相结合(我敢肯定你会使用它!),或者将其放入gdb中


很可能您忽略了已完成的套接字。这需要在同行启动关机时完成。< /P> Valgrind是C/C++,而不是java。“天地万物,霍雷肖”:)无论如何,谢谢。将
java
linux
标记一起使用并没有什么错。我可以这样做,但这实际上是一个临时解决方案,直到它再次增长。我们试图关闭套接字,但似乎确实存在一个被遗忘的问题。“一种方法是使用探查器运行应用程序。这很可能会发现问题,即使您无法准确再现客户的问题。”探查器能否捕获此类问题?适当使用探查器可以检测资源(例如套接字)的存在可能不会被注意到的泄漏。我们发现YourKit profiler具有内置的套接字监视功能,这对查找打开的套接字非常有帮助,这最终解决了所有描述符泄漏问题。@SyBer除了
YourKit
,任何其他免费选项?在Ubununtu上,您可能需要将
--program
选项传递给netstat,以便输出进程id(即PID)。