[翻译]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中被移除): 使用或禁用增量式concurrent
GC 算法-XX:+/-CMSConcurrentMTEnabled
: 使用或禁用并行(多线程)concurrent
GC 算法-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交互 |