Java NIO 导致文件描述符泄漏
我们有一个基于Java NIO实现的http服务器。 它在 Ubuntu 10.04.2 LTS 上运行,java 版本为“1.6.0_20” Java(TM) SE 运行时环境(版本 1.6.0_20-b02) Java HotSpot(TM) Server VM(版本16.3-b01,混合模式)
但是,它泄漏了文件描述符,所有文件描述符都是unix域套接字。
当使用命令“netstat -anp”时,我们可以发现该进程只打开了两个unix域套接字。 然而,当使用 lsof -p 时,我们可以发现有大量的文件描述符,这些文件描述符是unix域套接字,并且与netstat中找到的设备值和节点值相同。
我检查了我们的代码,所有 SocketChannel 都已正确关闭。
是Sun JDK的bug吗? 我们该如何解决它?
We have a http server which is implemented based on Java NIO.
It is running on Ubuntu 10.04.2 LTS with java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Server VM (build 16.3-b01, mixed mode)
However, it leaks file descriptors, all of them are unix domain sockets.
When use the command "netstat -anp", we can find that the process only opens two unix domain socket.
However, when use lsof -p , we can find that there are huge amounts of file descriptors which are unix domain socket and have the same device value and node value as the one find in netstat.
I have checked our code, and all of the SocketChannels are closed properly.
Is it a bug of Sun JDK?
How can we fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根本原因找到了。
在我们的代码中,当我们关闭socketchannel时,我们也取消了该密钥。问题是:
一个。我们在select线程中取消key,并在另一个线程中关闭socketchannel
b.套接字通道将关闭,直到调用 key.cancel。
通过阅读close和cancel的实现,我们可以发现unix域套接字被dup2打开并且有时从未关闭(并发问题)。
The root cause is found.
In our code, when we close socketchannel, we also cancel the key. The problem is that:
a. We cancel the key in the select thread, and close the socketchannel in another thread
b. The socket channel is closed until the key.cancel is invoked.
By reading the implementation of close and cancel, we can find that the unix domain socket is opened by dup2 and never closed some times (concurrent issue).
我相信选择器使用 Unix 域套接字。你要关闭它们吗?
I believe Selectors use Unix domain sockets. Are you closing them?