[toc]
既然抉择了远方,即便天寒地冻,路遥马亡,我本就赤贫如洗,又有何惧。
串行收集器
- 单线程、独占式进行垃圾回收
- 独占式:应用程序线程会进行工作,只有垃圾回收线程在工作,即
stop the world
。 - 在并行能力较差的机器上,会有更好的性能体现。
新生代串行收集器
- 新生代串行收集器应用的是 复制算法
- 应用
-XX:UseSerialGC
,-XX:+UseConcMarkSweepGC -XX:-UseParNew
启用 GC
日志如下所示
[GC (Allocation Failure) [DefNew: 67932K->0K(78720K), 0.0002327 secs] 68792K->859K(253504K), 0.0002491 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
老年代串行收集器
- 老年代串行收集器应用的是 标记 - 压缩算法
- 应用
-XX:UseSerialGC
、-XX:+UseParNewGC
启用 GC
日志如下
[Full GC (Allocation Failure) [Tenured: 10250K->10249K(15360K), 0.0187416 secs] 10250K->10249K(19968K), [Metaspace: 9228K->9228K(1058816K)], 0.0187608 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
并行收集器
ParNew
- 新生代垃圾回收器
- 新生代串行收集器的多线程版本
- 与新生代串行收集器的区别仅在于垃圾回收时,是多线程并行。
- 应用
-XX:UseParNew
、-XX:UseConcMarkSweepGC
启用 GC
日志如下
[GC (Allocation Failure) [ParNew: 82K->24K(4608K), 0.0003178 secs][Tenured: 15353K->10251K(15360K), 0.0185459 secs] 15435K->10251K(19968K), [Metaspace: 8855K->8855K(1056768K)], 0.0188925 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
ParallelGC
- 新生代垃圾回收器,应用 复制算法
- 与
ParNew
相比,ParallelGC
更关注吞吐量 -XX:MaxGCPauseMillis
:设置最大垃圾进展工夫。例:-XX:MaxGCPauseMillis=200
-XX:GCTimeRatio
:设置吞吐量大小。取值范畴为0~100
的整数。若值为n
,那么JVM
将破费不超过1/(1+n)
的工夫在GC
上。例:-XX:GCTimeRatio=99
-XX:+UseAdaptiveSizePolicy
:自适应调整 新生代大小、eden 和 survivor 比例,以及降职老年代对象年龄等参数- 可通过
-XX:+UseParallelGC
、-XX:+UseParallelOldGC
启用 GC
日志如下
[GC (Allocation Failure) [PSYoungGen: 2410K->512K(4608K)] 12650K->10947K(19968K), 0.0016662 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
ParallelOldGC
- 老年代垃圾回收器,应用 标记 - 压缩算法
- 与
ParallelGC
统一,关注零碎吞吐量 ,ParallelOldGC
在jdk1.6
后(包含) 才能够应用 -XX:ParalleGCThreads
:设置GC
时,并行的线程数- 可通过
-XX:+UseParallelGC
、-XX:+UseParallelOldGC
启用 GC
日志如下
[Full GC (Allocation Failure) [PSYoungGen: 480K->0K(4608K)] [ParOldGen: 10499K->626K(15360K)] 10979K->626K(19968K), [Metaspace: 3063K->3063K(1056768K)], 0.0043604 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
CMS
CMS
是一款 低进展 的 老年代 垃圾收集器。个别与 Serial
, ParNew
新生代收集器一起工作,默认是 ParNew
。
工作流程细化为以下几个步骤
- 初始化标记(
stop the world
) - 并发标记
- 预清理
- 从新标记(
stop the world
) - 并发清理
- 并发重置状态期待下次
CMS
触发
初始化标记
stop the world
- 标记老年代
GC Root
对象 - 标记老手代援用老年代的对象
并发标记
- 与利用线程 并发执行,从上一步标记的节点顺着援用链路往下标记
- 并发标记过程中,老年代会产生新的对象、老年代援用会变更等等。为了进步从新标记的效率,这些对象所在的
card
会被标记为dirty
。 - 这一阶段,可能会导致
concurrent mode failure
预清理
与利用线程 并发执行 ,解决上一个阶段被标记为 dirty
的对象。该阶段为了缩小 从新标记 产生的进展工夫, 有可能 会期待一次 ygc
从新标记
stop the world
- 从
dirty
和root
持续往下标记可达对象
并发清理
- 与利用线程 并发执行
- 采纳 标记 - 革除 算法将垃圾革除
concurrent mode failure
在并发清理阶段,提到,有可能会产生 concurrent mode failure
景象。
呈现该景象的实质起因如下:
老年代没有足够的空间调配对象,从而导致应用 Serial Old
垃圾收集器触发一次 Full GC
主要参数
- -XX:ConcGCThreads, -XX:ParallelCMSThreads
CMS
默认启动的并发线程是(ParallelGCThreads + 3)/ 4
.ParallelGCThreads
示意新生代GC
线程数量。-XX:ConcGCThreads -XX:ParallelCMSThreads
可手动指定CMS
并发线程 - -XX:+CMSScavengeBeforeRemark
在进行 从新标记 阶段时,会执行一次ygc
- -XX:CMSInitiatingOccupancyFraction
默认 68,当老年代空间使用率达到该值时,会执行一次CMS GC
- -XX:+UseCMSCompactAtFullCollection
使CMS
在垃圾收集实现后,进行一次内存碎片整顿,碎片整顿会stop the world
。 - -XX:CMSFullGCsBeforeCompaction
默认 0,设定进行多少次CMS
回收后,进行一次内存压缩 - -XX:CMSMaxAbortablePrecleanTime
默认 5000 毫秒,预清理阶段,期待ygc
最大工夫 - -XX:+CMSClassUnloadingEnabled
容许回收 Class
垃圾回收器组合
笔者无奈在 jdk1.8
上,测试出 serial + parallel old
组合。
参考
CMS 垃圾收集器