垃圾收集器优缺点总结

  • Parallel并行: 多条垃圾收集线程并行工作, 此时用户线程仍处于等待状态
  • Concurrent并发: 用户线程与垃圾收集线程同时执行, 用户程序继续执行, 而垃圾收集器运行于另一个CPU上.

垃圾收集器概览

针对新生代
  • Serial
  • ParNew
  • Parallel Scavenge
针对老年代
  • Serial Old
  • Parallel Old
  • CMS
最新万能版
  • G1
  • 收集器参数总结
Serial收集器

serial: 单线程
最原生的收集器, jdk1.3以前唯一的选择.
单线程收集器. 这里并不是指使用一个CPU或一条收集线程去完成垃圾收集工作, 而是指它在收集垃圾时, 必须暂停用户工作线程(Stop The World).

  • 收集模型


    垃圾收集器优缺点总结_第1张图片
  • 优点
    简单而高效. Client模式下新生代收集器常用. 收集100m左右新生代几十毫秒-100毫秒
  • 缺点
    用户停顿感体验差
ParNew收集器(parallel new)

parallel: 并行收集
new: 针对新生代
Serial收集器的多线程版本
使用参数 -XX:+UseParNewGC
限制线程数 -XX:ParallelGCThreads

  • 特性
    1.多线程收集
    2.只有ParNew收集器能与CMS收集器配合工作

  • 收集模型


    垃圾收集器优缺点总结_第2张图片
  • 优点
    多CPU环境收集效率比Serial收集器强, 单CPU下线程切换开销会降低其效率.

  • 缺点
    收集垃圾时Stop The World

Parallel Scavenge收集器

parallel: 并行收集
针对新生代
也称为吞吐量优先收集器
主要关注点在于精确控制吞吐量, 即减少GC停顿时间.
控制最大垃圾收集停顿时间: -XX:MaxGCPauseMillis
-XX:GCTimeRatio, 该参数主要设置垃圾收集时间占总时间的比率. 比如参数设置未19, 则最大GC时间占总时间的5%(1/ (1 + 19)), 默认值为99, 即允许最大1%(1/(1 + 99))的垃圾收集时间.
自动化开关: -XX:+UseAdaptiveSizePolicy自动调整新生代比率分配, 老年代晋升等细节参数.
使用此收集器的时候, 一般把自动化工作交给虚拟机, 我们只需要设置好-Xmx最大对, 如果关注最大停顿时间, 使用MaxGCPauseMillis参数, 如果关注吞吐量, 使用GCTimeRatio参数.

  • 收集模型
    与ParNew收集器一样
  • 优点
    可以精确控制吞吐量
  • 缺点
    原本10s收集一次, 每次停顿100ms, 设置完参数之后可能变成5s收集一次, 每次停顿70ms. 停顿时间变短, 但收集次数变多.
Serial Old收集器

Serial: 单线程
Old: 针对老年代
使用标记-整理算法
Serial收集器的老年代版本

  • 收集模型


    垃圾收集器优缺点总结_第3张图片

    主要在Client模式下的虚拟机使用.

  • 优点
    简单高效
  • 缺点
    停顿时间长
Parallel Old收集器

parallel: 多线程收集
old: 针对老年代
使用标记-整理算法
Parallel Scavenge收集器的老年代版本
在jdk1.6之前, 如果新生代选择了Parallel Scaenge收集器, 老年代除了Serial Old(PS Mark Sweep)收集器外别无选择.( 上面说过, Parallel Scavenge收集器无法与CMS-Concurrent Mark Sweep收集器搭配工作)
但是现在可以使用Parallel Scavenge + Parallel Old组合. 而不必像之前那样Prallel Scavenge + Serial Old组合.

  • 收集模型


    垃圾收集器优缺点总结_第4张图片
  • 优点
    1.多线程收集
    2.弥补了之前Parallel Scavenge + Serial Old的尴尬组合.
  • 缺点
    GC时间停顿
CMS收集器

CMS: Concurrent Mark Sweep 并发标记-清理收集器
CMS是一款以获取最短回收停顿时间为目标的收集器, 重视服务的响应速度.
基于标记-清除算法
-XX:+UseConcMarkSweepGC, 这个参数表示对于老年代的回收采用CMS

  • 运作机制
    1.初始标记(CMS initial mark)
    2.并发标记(CMS concurrent mark)
    3.重新标记(CMS remark)
    4.并发清除(CMS concurrent sweep)
    其中步骤1和3仍然需要Stop The World. initial mark仅需要标记GC Roots能直接关联到的对象, 速度很快. concurrent mark阶段进行GC Roots Tracing. remark是为了修正concurrent mark阶段因用户程序继续运行而导致变动的那一部分对象的标记记录, 停顿时间比initial mark稍长.
    整个过程耗时最长的是concurrent mark和concurrent sweep. 收集器线程可以与用户线程一起工作, 忽略掉initial mark 和remark , 从总体时间上来看可以当作CMS收集器回收过程是与用户线程一起并发执行的.
  • 收集模型


    垃圾收集器优缺点总结_第5张图片
  • 优点
    1.并发收集(concurrent)
    2.低停顿
  • 缺点
    1.对CPU资源非常敏感, 并发阶段会降低系统吞吐量. 默认线程数(CPU数量+3)/4, 也就是说CPU4个以上时, 不占用超过25%的CPU资源, 如果CPU数量少于4个时, CMS对系统吞吐量影响将会很大.
    针对这种情况, 虚拟机提供了一种CMS变种收集器i-CMS(Incremental Concurrent Mark Sweep). 这种收集器使用抢占式思想来让收集器线程与用户线程交替运行, 尽量减少GC线程占用资源的时间, 整体上GC时间会变长, 但吞吐量影响会降低一些. 目前该收集器被声明为deprecated, 不提倡使用.
    2.无法处理浮动垃圾(Floating Garbage). 随着程序的运行, 有一部分垃圾出现在标记过程之后, 清除过程之前, 这部分在本次GC中无法被CMS清除, 只能留到下一次GC, 这就是浮动垃圾. CMS不能像其它收集器那样等到老年代几乎完全被填满了再进行收集, CMS需要预留一部分空间提供并发收集时的程序运作使用. 默认设置下, CMS收集器在老年代使用了68%的空间后就会被激活.
    针对这种情况, 如果老年代增长不快, 可以调高参数-XX:CMSInitiatingOccupancyFraction的值来提高百分比, 以便降低内存回收次数以获取更好的性能. 如果参数调的太高, CMS运行期间预留的内存无法满足程序需要, 会出现Concurrent Mode Failure失败, 性能反而降低, 此时虚拟机会启动后备预案: 临时启动Serial Old收集器来重新进行老年代的垃圾收集, 这样停顿时间会很长.
    3.标记-清除算法会产生大量空间碎片. 大量的碎片会导致老年代空间剩余很大却无法被充分利用. 难以找到连续的空间分配大对象, 导致触发Full GC.
    针对这种情况, CMS提供了参数-XX:+UseCMSCompactAtFullCollection, 用于Full GC之后提供碎片整理, 内存整理的过程无法并发. 空间碎片问题解决了, 但停顿时间由于Full GC而边长了. 虚拟机还提供了另一个参数-XX:CMSFullGCsBeforeCompaction用于设置在执行多少次不压缩的Full GC后, 跟着来一次带碎片整理的Full GC.
G1收集器

G1: Garbage First
相比CMS收集器, G1收集器有两个改进点
1.G1基于标记-整理算法, 不会产生空间碎片
2.G1可以精确控制停顿, 既能让使用者明确指定在一个长度为M毫秒的时间片段内, 消耗在垃圾收集器上的时间不得超过N毫秒, 几乎是实时Java垃圾收集器的特征了.
G1入门介绍-ImportNew
G1详细介绍-CSDN

  • 运作机制
    图解G1收集机制
    G1关键技术
    简介
    G1收集器可以实现在基本不牺牲吞吐量的前提下提前完成低停顿的内存回收, 这是由于它能够极力避免全区域的垃圾收集, 之前的收集器的收集范围都是整个新生代整个老年代, 而G1将整个Java堆划分为多个大小固定的独立区域(Region), 并且跟踪这些区域里面的垃圾堆积程度, 在后台维护一个优先列表, 每次根据允许的收集时间, 优先回收垃圾最多的区域(Garbage First名称的由来). 由于优先列表的存在, 使得G1能在有限的时间内获得最高的收集效率.
收集器参数总结
垃圾收集器优缺点总结_第6张图片

你可能感兴趣的:(垃圾收集器优缺点总结)