在 Java 中有两种处理垃圾暂停的方法。
- 使用像 Zing 这样的并发收集器。他们可以获得 1-4 毫秒的最坏情况抖动,这比某些 C++ 程序更好,因为来自其他来源的抖动(即 GC 不是抖动的唯一原因)
- 创建更少的垃圾并使用堆外内存。在 C++ 中,所有内容实际上都是堆外的,实际上,您可以在 C++ 中执行的任何操作都可以在 Java 中执行,即使它不那么自然。
这是一个真实高频交易系统的例子。它在没有交易时每天早上 5:00 进行一次 full GC,Eden 大小为 8 GB,大于一天产生的垃圾量。
http://vanillajava.blogspot.co.uk/2011/06/how-to-avoid-garbage-collection.html
从OpenHFT/Java-Lang项目中,您可以做到这一点。
final DirectStore store = DirectStore.allocate(128L << 32); // give me 128 GB
final DirectBytes slice = store.createSlice();
// every record has say 128 bytes and a lock at the start so they can be locked individually
for(long l = 0; l < store.size(); l += 128) {
slice.positionAndSize(l, 128);
slice.busyLock(0L);
// change something
slive.writeLong(4L, l);
slice.unlock(0L);
}
// when finished with the store
store.free(); // still no GCs.
所以在这个例子中,我创建并初始化了十亿条记录。这几乎不使用 JVM 堆,也不会触发任何 GC。
如果您担心代码可能无法在需要时编译,您可以通过执行来触发代码提前编译。进行一两个单元测试并练习关键代码,直到它编译为止。这通常可以在不到一秒钟的时间内完成。
简而言之,如果 GC 是一个问题,那么总会有解决方案。您可以使用 Java 开发解决方案,在盒子外部有 19 微秒的延迟,不会触发任何 GC(即使是次要的)
为什么他建议让我们使用 C++ 服务器和语言。
大多数开发人员不知道如何编写低延迟 Java。在 C++ 中,有更多的开发人员这样做,这就是使用 C++ 的原因。然而,阻止低延迟并不是语言的一个特性,只是在 Java 领域缺乏技能。