为什么JDK NIO使用了这么多的anon_inode文件描述符?

5

我正在使用Sun的JDK 1.6.0_26版本和NIO(使用Netty),在lsof中看到了数百个文件描述符,它们都是anon_inode

$ lsof -np 11225 | fgrep -w anon_inode
java    11225 nobody   57u     0000                0,9         0     1386 anon_inode
java    11225 nobody   61u     0000                0,9         0     1386 anon_inode
java    11225 nobody   65u     0000                0,9         0     1386 anon_inode
java    11225 nobody   69u     0000                0,9         0     1386 anon_inode
java    11225 nobody   73u     0000                0,9         0     1386 anon_inode
java    11225 nobody   77u     0000                0,9         0     1386 anon_inode
java    11225 nobody   81u     0000                0,9         0     1386 anon_inode
java    11225 nobody   86u     0000                0,9         0     1386 anon_inode
java    11225 nobody   89u     0000                0,9         0     1386 anon_inode
java    11225 nobody   93u     0000                0,9         0     1386 anon_inode
java    11225 nobody   97u     0000                0,9         0     1386 anon_inode
[...]

我找不到一个清晰的解释来说明什么是匿名inode,我查看了Linux内核源代码中的fs/anon_inodes.c,似乎epoll使用它,但我不确定为什么会有这么多。我确实有多个“epoll循环”和定时器线程,但数量远不及我的anon_inode数量。


很难在没有更多信息的情况下说出来,比如一些代码。 - Matt Ball
套接字每个使用两个文件描述符,我会认为这些匿名i节点是文件描述符,因为它们不在文件系统上。 - Peter Lawrey
2个回答

6

很可能是epoll。从早期的JDK 1.6.x版本开始,选择器默认使用epoll,并且这个选择器实现使用的文件描述符比旧的选择器实现多,除了套接字本身使用的描述符之外。如果您为单个SocketChannel注册了几个Selectors,例如读取和写入的分开的Selectors,则还会使用更多的文件描述符。如果Netty使用NIO,那么它几乎肯定会使用选择器。在一个应用程序中,由于使用基于epoll的Selectors,我的文件描述符与套接字的比率约为4:1。可以通过更改java.nio.channels.spi.SelectorProvider属性来恢复到旧的选择器实现,并减少描述符的数量,但可能会以性能为代价(YMMV)。


1

也许这些i节点与内存映射的“文件”有关,这将转换为Java的直接字节缓冲区。系统调用mmap(2)通常在文件上操作(使用文件句柄)。但它还支持一个选项MAP_ANONYMOUS,以在没有实际文件句柄的情况下操作内存映射。这听起来像是可能需要在内部使用“匿名i节点”的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接