[翻译]Oracle JDK 1.7.0_04 及之后可用的GC
Contents
Jack Shirazi 告诉你 Oracle Java 7 update 4 及更高版本可以使用哪些GC和GC的组合, 包括Java 8 和Java9
发布日期: June 2012, 更新日期: September 2015, 作者 Jack Shirazi
注意, 这已经更新到 Java 8 和 Java 9
随着G1终于在 1.7.0_04(Java 7 update 4) 版本中正式得到官方支持 - 即不再是实验性GC了, 值得评估我们现在在 Sun JVM 中的GC可用性. 以下所有详细信息都与来自 1.7.0_04 的 Sun JVM 相关.
现在有七种主要的GC算法(其中一种 PS Scavenge) 有两种模式, 这两种模式足够不同, 我称它们为两种不同的算法.(即, 有没有自适应GC), 另一种( concurrent collector, 并发收集器)有大量的选项, 使得其中一种GC至少有6种算法. 列出GC是非常有用的, 所以这就是我要做的.
首先, 我将描述实际不同的主GC. 有七个(我将G1列为一个)
Young generation collectors
Copy (通过 -XX:+UseSerialGC 开启)
serial copy collector (串行复制收集器)使用一条线程将幸存对象从 eden 复制到 survivor 和 survivor 空间之间, 直到它们已经存在足够长的时间, 然后将它们复制到 old generation
PS Scavenge (通过 -XX:+UseParallelGC 开启)
parallel scavenge collector(并行扫描收集器), 与 Copy collector 类似, 但并行使用多条线程, 并具有一些如何收集 old generation 的信息(基本上是为了与 serial 与 PS old generation collector 一起工作而编写的)
ParNew (通过 -XX:+UseParNewGC 开启)
parallel copy collector(并行复制收集器), 类似 copy collector, 但并行使用多条线程, 并具有内部 callback: 允许与 old generation collector 对其收集的对象进行操作(实际上是为了与 concurrent collector 一起工作而编写的)
G1 Young Generation ( 通过 -XX:+UseG1GC 开启)
G1 收集器, 使用 Garbage First 算法, 将堆分成许多较小的空间, 但这些仍然分为 young generation 中的 eden, survivor 空间.
Old generation collectors
MarkSweepCompact ( 通过 -XX:+UseSerialGC 开启)
serial mark-sweep collector , 使用一个(一条线程) serial full mark-sweep garbage collection 算法, 并且可选压缩.
PS MarkSweep ( 通过 -XX:+UseParallelOldGC 开启)
parallel scavenge mark-sweep collector, 即 MarkSweepCompact 的并行版本(即使用多线程)
ConcurrentMarkSweep ( 通过 -XX:+UseConcMarkSweepGC 开启)
concurrent collector(并发收集器), 一种GC算法, 它试图在后台执行大部分的GC工作, 而不会停止应用程序线程的工作线程(仍有一些阶段, 它必须停止应用程序线程, 但这些阶段试图保留最小). 请注意, 如果 concurrent collector 无法跟上垃圾的话, 它将故障转移到下次GC的 serial MarkSweepCompact collector.
G1 Mixed Generation ( 通过 -XX:+UseG1GC 开启)
G1 收集器, 使用 Garbage First 算法, 将许多堆分成更小的空间.
除了 ConcurrentMarkSweep 之外, 所有的GC算法都是 stop-the-world 的, 即它们在工作时会停止所有的应用程序线程-停止被称为 暂停时间 (pause time). ConcurrentMarkSweep 试图在后台完成大部分工作, 并尽量缩短暂停时间, 但它也有一个 stop-the-world 阶段, 并且可能会陷入 full stop-the-world 的 MarkSweepCompact(G1 收集器有一个 concurrent 阶段, 但目前大多是 stop-the-world)
GC 的组合
这是一组可用的GC, 但它们在两上不同的堆空间中运行, 并且它是我们实际结束特定JVM设置的组合, 因此我还会列出可能的组合. 它不会爆炸成十几种组合, 因为并非所有这些GC都能相互协作. G1 实际上是 antisocial collector , 不喜欢与其他人一起工作; serial collector 是一个 last man picked 收集器(译注: 即最后一个选择的); PS collector 喜欢与其他协作; ParNew 和 concurrent 喜欢一起工作. 从Java 9来说, 它几乎就是这样(除了能够关闭自适应大小调整策略之外), 在此之前, 它并不那么简单, 所以这里列出了我认为是GC的主要选项收集算法选项. 对于那些喜欢一些琐事的人来说, 我们实际上已经丢失了一段GC算法. train (增量) GC 可以在各种JVM如 -Xincgc 和 -XX:+UseTrainGC 这些标志不再适用, 前一个选项只是静默地转换为使用 ParNew 和 concurrent, 而后一个选项将导致此JVM 启动错误, 并且在Java 9中, 我们也失去了 concurrent collector 的增量算法.
可以工作的可用的GC算法组合的完整列表如下:
| 组合选项 | 实际的收集器组合 |
|---|---|
| XX:+UseSerialGC | young Copy and old MarkSweepCompact |
| -XX:+UseG1GC | young G1 Young and old G1 Mixed |
| -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy | young PS Scavenge old PS MarkSweep with adaptive sizing |
| -XX:+UseParNewGC (Java 8 中废弃, Java9中被移除, 但下面一行并不废弃) | young ParNew old MarkSweepCompact |
| -XX:+UseConcMarkSweepGC -XX:+UseParNewGC | young ParNew old ConcurrentMarkSweep** |
| -XX:+UseConcMarkSweepGC -XX:-UseParNewGC (Java 8 中废弃, Java 9 中被移除) | young Copy old ConcurrentMarkSweep** |
如果添加另一个未列出的GC算法, 则此处列出的所有组合都将无法启动JVM, 但
-XX:+UseParNewGC只能与 `-XX:+UseConcMarkSweepGC** 组合使用.有许多可用于
-XX:+UseConcMarkSweepGC的选项, 它可以改变算法, 例如:-XX:+/-CMSIncrementalMode: (java 8 中废弃, Java9中被移除): 使用或禁用增量式concurrentGC 算法-XX:+/-CMSConcurrentMTEnabled: 使用或禁用并行(多线程)concurrentGC 算法-XX:+/-UseCMSCompactAtFullCollection: 地full GC发生时使用或禁用压缩
其他等同是以上之一的选项:
| 它们自己在命令行选项使用时 | 等同于上表之一 |
|---|---|
| -XX:+UseParallelGC | -XX:+UseParallelGC -XX:+UseParallelOldGC |
| -XX:+UseParallelOldGC | -XX:+UseParallelGC -XX:+UseParallelOldGC |
| -Xincgc (java 8 中废弃, java 9 中被移除) | -XX:+UseParNewGC -XX:+UseConcMarkSweepGC |
| -XX:+UseConcMarkSweepGC | -XX:+UseParNewGC -XX:+UseConcMarkSweepGC |
| 在大部分 Windows 中没有选项时 | -XX:+UseG1GC (java 9 的话), -XX:+UseSerialGC (<java 9 参考 |
| 在大部分 Unix 中没有选项时 | -XX:+UseG1GC (java 9的话), (<java 9) -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy , 参考 |
| -XX:+AggressiveHeap | -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy 与一堆其他选项有关的大小内存和线程, 以及它们如何与OS交互 |