为此,我使用了一个名为 Java Chronicle 的库。它旨在每秒保持和排队一百万个报价,而不会产生任何重大垃圾。
我在这里有一个演示,它以每秒 100 万条消息的速度发送带有纳秒计时信息的对象,它可以在 32 MB 堆的 JVM 中发送数千万条消息,而不会触发甚至是次要的收集。在我的超极本上,90% 的时间往返延迟小于 0.6 微秒。;)
从性能的角度来看,我通过第二种方法获得什么还是第一种更有意义?
我强烈建议不要用垃圾填充 CPU 缓存。事实上,我避免了任何会产生任何重大垃圾的构造。您可以构建一个系统,每个事件端到端创建少于一个对象。我有一个 Eden 大小,它比我一天产生的垃圾量还大,所以不用担心 GC 是次要的或满的。
以前有人实施过这种模式吗?
五年前,我用 Java 编写了一个可盈利的低延迟交易系统。当时它在 60 微秒的滴答声中足够快,可以用 Java 进行交易,但现在你可以做得比这更好。
如果你想要低延迟的市场数据处理系统,我就是这样做的。您可能会发现我在 JavaOne 上的演示文稿也很有趣。
http://www.slideshare.net/PeterLawrey/writing-and-testing-high-frequency-trading-engines-in-java
编辑我添加了这个解析示例
ByteBuffer wrap = ByteBuffer.allocate(1024);
ByteBufferBytes bufferBytes = new ByteBufferBytes(wrap);
byte[] bytes = "BAC,12.32,12.54,12.56,232443".getBytes();
int runs = 10000000;
long start = System.nanoTime();
for (int i = 0; i < runs; i++) {
bufferBytes.reset();
// read the next message.
bufferBytes.write(bytes);
bufferBytes.position(0);
// decode message
String word = bufferBytes.parseUTF(StopCharTesters.COMMA_STOP);
double low = bufferBytes.parseDouble();
double curr = bufferBytes.parseDouble();
double high = bufferBytes.parseDouble();
long sequence = bufferBytes.parseLong();
if (i == 0) {
assertEquals("BAC", word);
assertEquals(12.32, low, 0.0);
assertEquals(12.54, curr, 0.0);
assertEquals(12.56, high, 0.0);
assertEquals(232443, sequence);
}
}
long time = System.nanoTime() - start;
System.out.println("Average time was " + time / runs + " nano-seconds");
当使用 -verbose:gc -Xmx32m 设置时,它会打印
Average time was 226 nano-seconds
注意:没有触发 GC。