我们有一个基于Java NIO实现的http服务器。 它运行在Ubuntu 10.04.2 LTS上,java版本为“1.6.0_20” Java(TM)SE运行时环境(版本1.6.0_20-b02) Java HotSpot(TM)服务器VM(版本16.3-b01,混合模式)
但是,它泄漏了文件描述符,所有这些都是unix域套接字。
当使用命令“netstat -anp”时,我们发现该进程只打开两个unix域套接字。 但是,当使用lsof -p时,我们可以发现有大量的文件描述符是unix域套接字,并且具有与netstat中找到的相同的设备值和节点值。
我已经检查了我们的代码,并且所有SocketChannel都已正确关闭。
这是Sun JDK的错误吗? 我们如何解决它?
答案 0 :(得分:2)
找到了根本原因。 在我们的代码中,当我们关闭socketchannel时,我们也取消了密钥。问题是: 一个。我们在select线程中取消键,然后在另一个线程中关闭socketchannel 湾套接字通道关闭,直到调用key.cancel。
通过阅读close和cancel的实现,我们可以发现unix域套接字是由dup2打开的,并且从未关闭过几次(并发问题)。
答案 1 :(得分:0)
我相信选择器使用Unix域套接字。你在关闭它们吗?