Java NIO Windows 实现

4
在使用NIO.2 AIO功能开展项目时,我查看了“旧”的NIO选择器实现,并发现在Windows上使用默认的select函数,由于其内部实现不良而完全无法扩展。众所周知,在Windows上,IOCP是唯一真正的解决方案。当然,回调完成模型并不适合于NIO选择器模型,但这是否有效地意味着在Windows上使用NIO基本上不是一个好主意?
例如:新的AIO功能包括一个IOCP实现。
特别是在最新的Netty框架中,支持AIO已经被放弃。因此,Netty在Windows上的速度不如其本应达到的速度?
3个回答

4

NIO.2采用IOCP

下面的调用树通过在多个被调用的类名中包含"Iocp",演示了文件i/o方面的使用,来自Java 7:NIO.2文件通道的测试台< / a>。

另请参见sun.nio.ch.Iocp.java,“封装I / O完成端口的 AsynchronousChannelGroup 的Windows实现”。

NIO不使用IOCP,因为它仅支持“非阻塞i / o”(选择器),而不支持仅在NIO.2中添加的“异步i / o”(完成处理程序)。

enter image description here


3

我认为你混淆了异步与更快的概念。当然,NIO缓冲区比序列化相同数据的速度要快,但许多AIO技术会产生成本和延迟,这可能使得同步IO具有优势。

以前有一篇文章对各种IO技术进行了一些很好的基准测试,结果有点令人惊讶。Netty的开发人员可能决定与性能更好的(阻塞)IO模型保持一致。


幻灯片很棒。但我特别谈论的是Windows。整个IO vs NIO问题对我来说非常清楚,NIO更多地涉及可扩展性。在<1000个线程的情况下,IO表现更好,而NIO在5k及以上时显示出其优势。但是,在Linux上,NIO使用的是可扩展的选择方法,如epoll和kqueue。但是,在Windows上,标准的posix select函数非常糟糕,由于Windows的实现细节,因此应始终使用IOCP。 - Kr0e
有一个sun.nio.ch.Iocp类,所以我真的不理解NIO为什么不使用IOCP。如果它在您的环境中没有被使用,也许可以启用它。也许你正在运行一个非常古老的JVM。或者可能是其他什么问题。我只是很难相信会为了不让它可访问而编写一个Java类并将其包含到JVM支持库中。 - Edwin Buck
这个类只被AsychronousChannelGroup使用,它涉及AIO。nio的选择器部分只使用WindowsSelectorImpl。http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/sun/nio/ch/WindowsSelectorImpl.java - Kr0e
你提到的那篇文章比较了 阻塞 I/O 和 NIO 的 非阻塞 I/O。但是它没有提到由 NIO.2 实现的 异步 I/O - Evgeniy Berezovsky

0

IOCP 和 Java 的问题在于 IOCP 创建和管理线程。我的理解是,为了使 IOCP 在 Java 中工作,事件系统实际上必须通过 Windows IOCP 线程,然后按计划在 Java 线程池上执行。这使得 IOCP 在 Java 中的实现非常昂贵,与 C++/C# 相比。

AIO 可能已经从 Netty 中删除,因为没有人想牺牲 450,000 潜在交易来使用 AIO 而不是 NBIO。AIO 和 NBIO 之间的事务性能差距非常巨大。


IOCP 不会创建线程。 - GDI512

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