Jvm 垃圾收集器

垃圾收集算法:为实现垃圾回收提供理论支持

垃圾收集器:利用垃圾收集算法,实现垃圾回收的实践落地。

各种垃圾收集器之间也是可以配合使用的:

比如 CMS 可以和ParNew配合,CMS 和 Parallele Scavenge 不能使用。

下图中表示了各个垃圾收集器作用的范围,以及各个垃圾收集器之间可以配合使用的关系

     

 Stop The World

简写为 STW,也叫全局停顿,Java代码停止运行,native 代码继续运行,但不能与JVM进行交互。 原因:多半由于垃圾回收导致;也可能是 Dump线程,死锁检查、 Dump 堆等导致。Stop The World 会导致服务停止,请求没有响应;主从切换,危害生产环境

并行收集  vs 并发收集

并行收集:指多个垃圾收集线程并行工作,但是收集过程中,用户线程(你的业务线程)还是处于等待状态。

并发收集:指用户线程与垃圾收集线程同时工作

吞吐量

  • 吞吐量是指CPU用于运行用户代码的时间与CPU总消耗时间的比值。
  • 计算公式:运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)。比如Jvm已经运行了80分钟,垃圾收集总共花费了1分钟,也就是 80/81


垃圾收集器

1. Serial 收集器

采用复制算法。是新生代的垃圾收集器。

  • 是单线程的收集器。
  • 收集过程全程 Stop The World。
  • 适用于客户端程序,以 -client运行,默认就是使用 Serial。
  • 适用于单核机器

 2. ParNew 收集器

Serial 收集器德多线程版本,除使用了多线程外,其余和 Serial收集器一样。包括:JVM参数,Stop The World 的表现,垃圾收集算法都是一样的。

  • 多线程
  • 可以使用 -XX:ParallelGCThreads 设置垃圾收集的线程数。一般设置成同CPU核心数就可以了。
  • 主要用来和 CMS 配合使用

 3. Parallele Scavenge

Parallele Scavenge 收集器 关注的是吞吐量。适用于注重吞吐量的场景

  • 也叫做吞吐量优先收集器
  • 采用复制算法
  • 也是并行的多线程收集器,这一点和 ParNew类似
  • Parallele Scavenge 的特点 :
    • 可以达到一个可控制的吞吐量
      • -XX:MaxGCPauseMillis  : 控制最大的垃圾收集停顿时间(尽力)。比如设置100ms,垃圾收集每次时间尽量不超过100ms
      • -XX:GCTimeRatis : 设置吞吐量的大小,取值0-100,系统花费不超过   1/(1+n) 的时间用于垃圾收集
    • 自适应垃圾收集策略 : 可用  -XX:+UseAdptiveSizePolicy  打开。
      • 打开自适应策略后,无需手动设置新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)等参数。虚拟机会自动根据系统的运行状况收集性能监控信息,动态的调整这些参数,从而达到最优的停顿时间以及最高的吞吐量

4. 老年代收集器 Serial Old 收集器 

Serial Old 收集器 是  Serial 的老年代版本。采用标记-整理算法。适用场景:

  • 可以和Serial  、ParNew  、Parallel Scavenge 这三个新生代的垃圾收集器配合使用
  • CMS收集器出现故障的时候,会用 Serial Old 作为后备

 5. 老年代收集器 Parallel Old 收集器 

Parallel Old 是 Parallele Scavenge 的老年代版本。采用 标记-整理算法。

  • 只能和  Parallele Scavenge 配合使用。所以适用场景也是关注吞吐量的场景

  6. 老年代收集器 CMS 收集器 

CMS :Concurrent Mark Sweep 。 并发收集器。使用 标记-清除算法。上文讲的都是串行、并行收集器。

1. 初始标记

  • 标记GC Roots能直接关联到的对象,会 Stop The World

2. 并发标记 (concurrent mark)

  • 找出所有GC Roots 能关联到的对象。并发执行,无 Stop The World

3. 并发预清理(concurrent-preclean)此阶段可能会执行可能不会执行

  • 重新标记那些在并发标记阶段,引用被更新的对象,从而减少后面重新标记阶段的工作量。无 Stop The World 
  • 可使用 XX:-CMSPrecleaningEnabled 关闭并发预清理阶段,默认打开

4. 并发可中止的预清理阶段(concurrent-abortable-preclean)  经过并发预清理之后,又会经过一个可能会执行可能不会执行的阶段

  • 和并发预清理做的事情一样,此阶段并发执行,无 Stop The World
  • 当Eden的使用量大于CMSScheduleRemarkEdenSizeThreshold 的阈值(默认2M)时,才能执行该阶段
  • 并发可中止的预清理阶段的主要作用是:允许我们能够控制预清理阶段的结束时机。比如扫描多长时间(CMSMaxAbortablePrecleanTime,默认5秒)或者 Eden 区使用占比达到一定的阈值(CMSScheduleRemarkEdenPenetration,默认50%)就结束本阶段

5. 重新标记(remark)

  • 修正并发标记期间,因为用户程序继续执行,导致标记发生变动的那些对象的标记
  • 一般来说,重新标记花费的时间会比初始标记阶段长一些,但比并发标记的时间短。
  • 此阶段 会 Stop The World 

6. 并发清理(concurrent sweep)

  • 基于标记结果,清除掉前面标记出来的垃圾。此阶段并发执行, 无 Stop The World 

7. 并发重置(concurrent reset)

  • 清理本次CMS GC的上下文信息,为下一次GC做准备

CMS 收集器 优点

  • Stop The World 时间短
  • 大多过程并发执行

CMS 收集器 缺点

  • CPU资源比较敏感,并发阶段可能导致应用吞吐量的降低
  • 无法处理浮动垃圾。并发清理阶段业务还在运行,会产生新的垃圾,这部分的叫浮动垃圾
  • 不能等到老年代几乎满了才开始收集。预留的内存不够 →引发了“Concurrent Mode Failure”问题 →使用“Serial Old”垃圾回收器作为后备
  • 可使用 CMSInitiatingOccupancyFraction 设置老年代占比达到多少就触发垃圾收集器,默认是68%
  • 内存碎片的问题。因为是使用标记-清除。
  • XX:+UseCMSCompactAtFullCollection”,默认就打开了。意思是在Full GC之后要再次进行“Stop the World”,停止工作线程,然后进行碎片整理,就是把存活对象挪到一起,空出来大片连续内存空间,避免内存碎片。
  • -XX:CMSFullGCsBeforeCompaction”,这个意思是执行多少次Full GC之后再执行一次内存碎片整理的工作,默认是0,意思就是每次Full GC之后都会进行一次内存整理。

CMS 收集器适用场景:希望体统停顿时间短,响应速度快的场景,比如各种服务器应用程序

G1 收集器

G1 收集器 全称 Garbge First , 是面向服务器端的应用的垃圾收集器。G1 把内存划分为大小相等的 Region 。

通过参数:-XX:G1HeapRegionSize 指定Region的大小,取值范围 1 ~ 32 MB。一定要是2的N次幂。把大对象(超过 Regiony一半大小)放在 Humongous 中

它既可以用在新生代,也可以用在老年代。

G1 收集器 设计思想

把内存区域分为若干个Region,然后去跟踪每一个 Region里面垃圾堆积的价值大小,若回收掉这个Region,能够获得多少剩余的空间,之后G1收集器会在后台构建一个优先列表,根据上面的价值大小,做了个排序。同时会根据设置的允许的收集时间,去优先回收价值高的Region。这样就可以获得一个更高的垃圾回收效率。这就是前文提到的增量算法的思想

G1 收集器  - 垃圾收集机制

G1提供了三种垃圾垃圾机制:

  • Young GC
  • Mixed GC
  • Full GC

Young GC

  • 当所有Eden Region 都满了的时候,就会触发Young GC
  • Eden 里面的存活对象会转移到 Survivor Region 里面去
  • 原先 Survivor Region 中的存活对象转移到新的 Survivor Region中,或者(15次)晋升到 Old Region
  • 空闲的Region会被放入空闲列表中,等待下次被使用

Mixed GC

Mixed GC 是G1最能体现设计思想的地方。

  • 当老年代大小占整个堆的百分比达到一定阈值(可用 -XX:InitiatingHeapOccupancyPercent指定,默认45%),就触发Mixed GC
  • Mixed GC  会回收所有 Young Region , 同时回收部分 Old Region。要回收的这部分 Old Region 是根据设置的允许的收集时间,前面讲的回收价值高的Region 去选择

Mixed GC 执行过程

1. 初始标记

  • 标记GC Roots能直接关联到的对象,存在 Stop The World 。和CMS类似

2.并发标记 (concurrent mark)

  • 同CMS的并发标记,并发执行,没有stw

3. 最终标记(Final Marking)

  • 修正在并发标记期间引起的变动,存在 Stop The World 

4. 筛选回收(Live Data Counting and Evacuation)

  • 对各个Region的回收价值和成本进行排序
  • 根据用户所期望的停顿时间(MaxGCPauseMillis)来制定回收计划,并选择一些Region回收。存在 Stop The World 
    • 回收过程:选择一系列Region构成一个回收集(放到一个set集合里),把决定回收的Region中的存活对象复制到空的Region中,删除掉需要回收的Region ->无内存碎片

Full GC 

  • 复制对象内存不够,或者无法分配足够的内存(比如巨型对象没有足够的连续区分分配)时,会触发Full GC。Full GC 使用 Serial Old 模式。会长时间的 STW.
  • G1 优化原则:尽量减少Full GC 的发生
    • 增加预留内存(增大-XX:G1ReservePercent,默认为堆的10%)
    • 更早的回收垃圾(减少 -XX:InitiatingHeapOccupancyPercent,老年代达到该值就触发 Mixed GC,默认是45%)。就是尽量让GC发生在 Young GC、Mixed GC

其它垃圾收集器

  • Shenandoah
  • ZGC
  • Epsilon

如何选择垃圾收集器

  1. 应用系统关注的主要矛盾点是什么(吞吐量? 低延迟?)
  2. 基础设施(服务器硬件、系统)
  3. jdk版本

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值