1

在我们的一个客户系统中,我们面临打开文件过多错误,目前 FD 限制设置为最大值,并且每周发生一次。

在看到 lsof 和 netstat o/p 之后,我能够看到太多的 Sockets 处于 BOUND 状态(20K)。据我了解,这种状态是一种瞬态,我无法找到它实际泄漏的位置。当我在 heapDump 中看到有界套接字之一时,我看到以下 GC 引用

>java.net.InetSocketAddress
 >> sun.nio.ch.SocketChannelImpl
  >>>sun.nio.ch.SocketAdaptor
   >>>>java.net.SocksSocketImpl
    >>>>>java.lang.ref.Finalizer 

我不知道如何解决这个问题。我需要专家意见吗?

4

3 回答 3

3

为了确保套接字是 close()d,它从终结器线程中关闭。

Finalizer 线程是单线程的,如果它运行缓慢(例如,因为您没有正确关闭连接),您创建套接字的速度可能比清理它们的速度快。

首先要检查的是进行堆栈转储并查看终结器线程通常在等待什么。其次,检查完成后是否始终关闭套接字连接。套接字仍将被添加到终结器队列中,但它们不会花费任何时间来检查它们是否已经关闭。

于 2012-07-25T15:55:11.850 回答
1

您严重泄漏套接字。当您应该在某个地方关闭它们时,您不会在 finally 块中关闭它们。我会从 BOUND 状态猜测,你在某个地方调用 new Socket(),然后调用 connect(),如果它失败了,你并没有关闭一个套接字,但可能还有很多其他的可能性。

于 2012-07-26T02:11:04.573 回答
0

感谢您的提示,我们能够找出问题所在。. 实际上 nio 抛出了一个 unresolvedAddress 异常,在这种情况下,soket 资源没有被清理,但是当 IOException 引发时,所有资源都被清理并释放,现在我们只处理 UnresolvedAddressException。. 修复很简单,但需要时间来解决问题:)

于 2012-08-03T06:08:21.690 回答