简体   繁体   English

替代 Java 选择器实现

[英]Alternative Java Selector Implementations

I'm writing a high performance/low garbage application (microseconds matter) that has a.networking component.我正在编写一个具有网络组件的高性能/低垃圾应用程序(微秒很重要)。 One of the sore points that I've come across is the implementation of the built in Selector for Java NIO.我遇到的痛点之一是 Java NIO 的内置选择器的实现。

A few things that are problematic:一些有问题的事情:

  • Lots of object creation.大量 object 创作。 Pretty much every call to selectedKeys() creates a lot of objects.几乎每次调用 selectedKeys() 都会创建很多对象。 Iterators, boxing/unboxing, you name it.迭代器、装箱/拆箱,应有尽有。 Not a problem with most other cases but the application I'm writing needs to create as little garbage as possible.大多数其他情况都不是问题,但我正在编写的应用程序需要创建尽可能少的垃圾。
  • Layers upon layers of locking and synchronization.层层锁定和同步。 At the time the selectorImpls were built, a bunch of the Java lock primitives didn't exist.在构建 selectorImpls 时,一堆 Java 锁原语并不存在。 As a result it's clunky and not optimal.结果,它很笨重而且不是最佳的。 In my use case, there's only one thread calling select so the locking is in fact useless.在我的用例中,只有一个线程调用select ,因此锁定实际上是无用的。

Extending or changing the selector implementation is a nonstarter.扩展或更改选择器实现是行不通的。 Most of the classes are final, with private and package-private members located in the sun.nio.ch.* package. Native methods also complicate things.大多数类都是最终类,私有成员和包私有成员位于sun.nio.ch.* package。本地方法也使事情复杂化。

Are there any other more modern implementations of the selector that may be more performant?是否还有其他更现代的选择器实现可能更高效?

The.networking libraries I've examined just use the built in Java selector under the covers.我检查过的网络库只是在幕后使用内置的 Java 选择器。 Any help would be appreciated.任何帮助,将不胜感激。

Maybe this lib satisfies your needs?也许这个库满足你的需求? Haven't used it myself, but looks promising.我自己没用过,但看起来很有希望。 http://www.coralblocks.com/index.php/the-simplicity-of-coralreactor/ http://www.coralblocks.com/index.php/the-simplicity-of-coralreactor/

Netty project has an implementation that uses Native epoll edge-triggered transport : Netty 项目有一个使用原生 epoll 边缘触发传输的实现

Since 4.0.16, Netty provides the native socket transport for Linux using JNI.从 4.0.16 开始,Netty 使用 JNI 为 Linux 提供本机套接字传输。 This transport has higher performance and produces less garbage [...]这种传输具有更高的性能并产生更少的垃圾 [...]

One possible drawback for you might be, it's available on Linux only.一个可能的缺点可能是,它仅在 Linux 上可用。

On the positive side, Netty is an open-source project, may be the source code will give you a hint or two.从积极的方面来说,Netty 是一个开源项目,可能源代码会给你一两个提示。

Regarding your first point about lots of object creation, you can ameliorate by using the select methods that were introduced in java11, the ones that accept an action Consumer as a parameter.关于您关于大量 object 创建的第一点,您可以使用 select 方法进行改进,这些方法是在 java11 中引入的,这些方法接受消费者作为参数。

Before java11, every time you call a select() method, you have to call iterator() to access the events.在 java11 之前,每次调用 select() 方法时,都必须调用 iterator() 来访问事件。 This would create a new iterator object which would be subject to garbage collection.这将创建一个新的迭代器 object,它将接受垃圾回收。 And this was unfortunately enshrined in the interface (abstract base class) itself.不幸的是,这被包含在接口(抽象基类)本身中。

The new methods iterate over the events themselves, applying your action, and reducing garbage.新方法迭代事件本身,应用您的操作并减少垃圾。

Here's the javadoc for the new methods: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/channels/Selector.html#select(java.util.function.Consumer,long)这是新方法的 javadoc: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/channels/Selector.html#select(java.util. function.消费者,长)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM