Java-8-垃圾收集调优指南4-可用的收集器(译).md

各种收集器的性能特点

对这一点的讨论是关于串行收集器(serial collector)的。Java HotSpot VM 包含三种不同类型的收集器,每一种具有不同的性能特点。

  • 串行收集器使用单个线程执行所有的垃圾收集工作,这使得它相对而言比较高效,因为没有线程间的通信开销。它最适合单处理器的机器,因为它不能利用多处理器硬件的优势,但是在多处理器上对小数据集(最大约 100 MB)的应用来说它还是有用的。在某些硬件和操作系统配置上默认选择串行收集器,或者可以使用选项 -XX:+UseSerialGC 显式地启用它。

  • 并行收集器(也称为 throughput collector)并行地执行 minor 收集,这可以显著地降低垃圾收集的开销。它适用于在多处理器或多线程硬件上运行的中到大型数据集的应用。在某些硬件和操作系统配置上默认选择并行收集器,或者可以使用选项 -XX:+UseParallelGC 显式地启用它。

    • parallel compaction 这个特性可使并行收集器并行地执行 major 收集。没有 parallel compaction,收集器就使用单个线程来执行 major 收集,这会显著地限制可扩展性(scalability)。如果命令行指定了 -XX:+UseParallelGC 选项,默认就会启用 parallel compaction 特性。想关掉这个特性就使用 -XX:-UseParallelOldGC 选项。
  • 并发为主的收集器(mostly concurrent collector)并发地执行它的大部分工作(例如,在应用仍在运行的同时)以保持垃圾收集引起的暂停较短。它适用于中到大型数据集且响应时间比总的吞吐量更重要的应用,因为用来最小化暂停时间的技术会降低应用的性能。Java HotSpot VM 提供了两个并发为主的收集器(mostly concurrent collector)供我们选择;请看 The Mostly Concurrent Collectors。使用选项 -XX:+UseConcMarkSweepGC 启用 CMS 收集器,或 -XX:+UseG1GC 启用 G1 收集器。

选择合适的收集器

除非你的应用对暂停时间有严格的要求,否则就先运行你的应用,让虚拟机去选择收集器。如有必要,可调整堆的大小以改进性能。如果性能仍不满足你的目标,就使用下面的指导方针作为选择收集器的起点。

  • 如果应用的数据集很小(最大约 100 MB),就使用选项 -XX:+UseSerialGC 选择串行收集器。

  • 如果应用将运行在单核处理器上,且对暂停时间没有要求,就让虚拟机去选择收集器,或者使用选项 -XX:+UseSerialGC 选择串行收集器。

  • 如果 (a) 应用的性能峰值是第一优先级的,且 (b) 对暂停时间没有要求或者大于等于 1 秒的暂停是可接受的,就让虚拟机去选择收集器,或者使用选项 -XX:+UseParallelGC. 选择并行收集器。

  • 如果响应时间比总的吞吐量更重要,且垃圾收集暂停必须保持短于约 1 秒,就使用选项 -XX:+UseConcMarkSweepGC-XX:+UseG1GC 选择并发收集器。

这些指导方针只是为选择收集器提供一个起点,因为性能取决于堆的大小、应用维持的活数据的数量、可用的处理器的数量和速度。暂停时间对这些因素特别敏感,因此之前提及的 1 秒的阈值只是一个近似值:并行收集器(parallel collector)会在许多数据大小和硬件的组合上经历长于 1 秒的暂停时间;相反地,在某些组合上并发收集器(concurrent collector)也许不能保持暂停短于 1 秒。

如果推荐的收集器不能实现想要的性能,首先尝试调整堆和分代的大小来满足想要的目标。如果性能仍然不好,就尝试一个不同的收集器:使用并发收集器来降低暂停时间,或者在多处理器硬件上使用并行收集器提高总的吞吐量。

参考资源

原文 Java 8 Garbage Collection Tuning Guide: Available Collectors

0%