总结
通过本节内容的学习, 你应该对 G1 垃圾收集器有了一定了解。当然, 为了简洁, 我们省略了很多实现细节, 例如如何处理 巨无霸对象(humongous objects)。 综合来看, G1 是 HotSpot 中最先进的 ** 准产品级(production-ready)** 垃圾收集器。重要的是, HotSpot 工程师的主要精力都放在不断改进 G1 上面, 在新的 java 版本中, 将会带来新的功能和优化。
可以看到, G1 解决了 CMS 中的各种疑难问题, 包括暂停时间的可预测性, 并终结了堆内存的碎片化。对单业务延迟非常敏感的系统来说, 如果 CPU 资源不受限制, 那么 G1 可以说是 HotSpot 中最好的选择, 特别是在最新版本的 Java 虚拟机中。当然, 这种降低延迟的优化也不是没有代价的: 由于额外的写屏障 (write barriers) 和更积极的守护线程, G1 的开销会更大。所以, 如果系统属于吞吐量优先型的, 又或者 CPU 持续占用 100%, 而又不在乎单次 GC 的暂停时间, 那么 CMS 是更好的选择。
总之: G1 适合大内存, 需要低延迟的场景。
选择正确的 GC 算法, 唯一可行的方式就是去尝试, 并找出不对劲的地方, 在下一章我们将给出一般指导原则。
注意,G1 可能会成为 Java 9 的默认 GC: http://openjdk.java.net/jeps/248
Shenandoah 的性能
译注: Shenandoah: 谢南多厄河; 情人渡, 水手谣; –> 此款 GC 暂时没有标准的中文译名; 翻译为大水手垃圾收集器?
我们列出了 HotSpot 中可用的所有 “准生产级” 算法。还有一种还在实验室中的算法, 称为 超低延迟垃圾收集器(Ultra-Low-Pause-Time Garbage Collector). 它的设计目标是管理大型的多核服务器上, 超大型的堆内存: 管理 100GB 及以上的堆容量, GC 暂停时间小于 10ms。 当然, 也是需要和吞吐量进行权衡的: 没有 GC 暂停的时候, 算法的实现对吞吐量的性能损失不能超过 10%
在新算法作为准产品级进行发布之前, 我们不准备去讨论具体的实现细节, 但它也构建在前面所提到的很多算法的基础上, 例如并发标记和增量收集。但其中有很多东西是不同的。它不再将堆内存划分成多个代, 而是只采用单个空间. 没错, Shenandoah 并不是一款分代垃圾收集器。这也就不再需要 card tables 和 remembered sets. 它还使用转发指针(forwarding pointers), 以及 Brooks 风格的读屏障(Brooks style read barrier), 以允许对存活对象的并发复制, 从而减少 GC 暂停的次数和时间。
关于 Shenandoah 的更多信息, 请参考博客: https://rkennke.wordpress.com/, JEP 文档: http://openjdk.java.net/jeps/189, 或者 Google 搜索 「Shenandoah GC」。