《JVM第9课》垃圾回收器

打印 上一主题 下一主题

主题 882|帖子 882|积分 2646

先来看一张图,串行代表两个垃圾回收器按顺序实验,并行代表同时实验。STW代表工作线程暂停,Stop The World的意思。
垃圾回收器实验顺序实验方式作用区域使用算法阐明Serial GC串行工作线程暂停,单线程举行垃圾回收新生代复制算法Serial Old GC串行工作线程暂停,单线程举行垃圾回收老年代标记-整理算法ParNew GC并行工作线程暂停,多线程举行垃圾回收新生代复制算法Serial GC的多线程版CMS GC并行用户线程和垃圾回收线程同时实验老年代标记-清除算法低暂停Parallel GC并行工作线程暂停,多线程举行垃圾回收新生代复制算法和ParNew相比能动态调整内存分配情况JDK8默认Parallel Old GC并行工作线程暂停,多线程举行垃圾回收老年代标记整理算法替代串行的Serial Old GCG1并行用户线程和垃圾回收线程同时实验整堆分区算法在耽误可控的情况下尽可能提高吞吐量JDK9默认ZGC并行用户线程和垃圾回收线程同时实验整堆分页算法STW的时间不超过1ms,且不会随着堆的大小增长而增长常用命令:
-XX:+PrintCommandLineFlags,检察使用的垃圾收集器
-XX:+UseSerialGC,指定使用Serial GC处理新生代,而且默认会使用Serial Old GC处理老年代
-XX:+UseParNewGC,指定新生代使用ParNew GC,-XX:+UseConcMarkSweepGC,指定老年代使用CMS GC
-XX:+UseParallelGC,指定新生代使用Parallel GC,-XX:+UserParallelOldGC,指定老年代使用Parallel Old GC,这两个配置一个,另一个自动激活
1. Serial GC、Serial Old GC

Serial GC和Serial Old GC是比较早的垃圾回收器,那个时间一样平常的服务器CPU还只有一核,所以一个线程举行垃圾回收就够了。串行的意思就是两个垃圾回收器不能同时实验。
2. Parallel GC、Parallel Old GC

Parallel GC举行垃圾回收时也会暂停用户线程(STW),与Serial GC的差别就是它时多线程举行垃圾回收的。下面画个图方便理解垃圾回收过程。

在一次垃圾回收过程中,会举行一次STW,而且会有多个线程同时举行垃圾回收,回收完后用户线程回复运行。
3. CMS GC

CMS全称是ConcMarkSweep,即并发标记清除。但是它不是某个JDK默认的,要使用的话就加上-XX:+UseConcMarkSweepGC参数。
CMS GC是Java9之前我们很常用的垃圾回收器,是针对老年代的使用标记-清除算法的垃圾回收器。我们一样平常会使用CMS GC替代默认的老年代垃圾回收器,因为CMS GC的特点是低暂停。实现低暂停的方法是在初始标记阶段只标记GC Roots直接可达的对象,这个阶段比较短,所以对用户线程来说是低暂停。
下面用一张图展示它的垃圾回收过程:

阶段一,初始标记:

  • STW,暂停所有用户线程。
  • 然后标记GC Roots直接可达的对象,就是第一层对象。
  • 一旦标记完就恢复用户线程继续实验。
  • 这个阶段很快。
阶段二,并发标记:

  • 从上一个阶段标记出的对象,开始遍历整个老年代,标记出所有的可达对象。
  • 耗时虽然比较长,但幸亏不需要STW,可与用户线程一起实验。
  • 采用的是三色标记算法(大家自行拓展)。
阶段三,重新标记:

  • 由于在并发标记阶段,应用程序线程也在运行,可能会导致一些对象的状态发生变革,例如新的对象被创建或旧的对象被删除。
  • 为了修正这些问题,需要举行一次短暂的停顿,重新检查并更新标记状态
  • 这个阶段也是“Stop-The-World”的,但也不会太长。
阶段四,并发清理:

  • 清除垃圾对象,开释空间供后续分配使用。
  • 清理工作与应用程序线程并发举行,不会引起停顿。
阶段五,并发重置:

  • CMS收集器会准备下一次垃圾回收循环,重置内部数据结构等。
  • 这一阶段也是与应用程序并发举行的。
CMS整个垃圾回收过程更长了,但是STW的时间变短了,而且在垃圾回收过程中大部门时间用户线程可以实验,所以用户体验更好了。
在并发清理过程中,可能用户线程会产生新的垃圾,这些就是“浮动垃圾”,只能比及下一次GC时来清理。
如果在并发标记、并发清理过程中,用户线程产生的新对象要进入老年代,但是老年代空间又不够,那么就会导致“concurrent mode failure”,此时就会利用Serial Old来做一次垃圾回收,就会做一次全局STW。
由于采用的是标记-清除算法,所以会产生内存碎片,可以通过参数 -XX:+UseCMSCompactAtFullCollection 让JVM在实验完标记-清除后再做一次整理,也可以通过 -XX:CMSFullGCsBeforeCompaction 来指定多少次GC后来做整理,默认是0,表示每次GC后都整理。
CMS垃圾回收器可以或许在大多数时间内与应用程序并发实验,淘汰了因垃圾回收引起的停顿时间。然而,CMS也有一些缺点,好比它可能产生大量的浮动垃圾(floating garbage),而且在某些情况下仍然会导致较长的停顿。随着Java版本的发展,G1 GC和ZGC等更先进的垃圾回收器逐渐取代了CMS的职位。
4. G1(Garbage-First)

G1垃圾回收器是在 Java 7 update4 之后引入,并在Java 9中成为默认的垃圾收集器的。G1的计划目标是提供高吞吐量的同时,实现可预测的暂停时间,特别适合处理大堆内存的应用场景。下面先容一些G1垃圾回收器的内存结构。
先看张图:

之前我们讲的垃圾回收器把堆内存分为Eden、S0、S1、老年代这四个区域,每个区域都是连续的。而在G1中,整块堆内存被分成2048个大小相等的region,这些region在物理上不要求是连续的,但在逻辑上是连续的。每个region可以独立地作为Eden、Survivor或老年代的一部门。所以说G1照旧把内存分为了Eden、Survivor、老年代区,只不外空间可以是不连续的了。
Humongous区是专门用来存放大对象的(如果一个对象大小超过了一个region的50%,那么就是大对象)
用一张图展示垃圾回收过程:

阶段一,初始标记:

  • 短暂的STW。
  • 标记出直接可达对象。
阶段二,并发标记:

  • 并发遍历整个堆,标记所有可达对象。
  • 不需要STW。
  • 三色标记。
阶段三,最终标记:

  • 这也是一个较短的STW。
  • 修正并发标记期间由于应用程序运行而可能产生的误差。
阶段四,筛选回收:

  • 需要STW,来清除垃圾对象。
  • 可通过 -XX:MaxGCPauseMillis 来指定GC的STW停顿的时间,所以可能并不会回收掉所有的垃圾对象,默认为200ms(略小于人的平均反应速率)。
  • 由于回收时间有限,所有会选择更有回收价值(垃圾更多)的区域举行回收。这也是Garbage-First(垃圾优先)的名字由来。
  • 采用的是复制算法,不会产生碎片(会把某个region里的可达对象移动到空白的region里)。
由于筛选回收阶段的STW时间可能不够用导致垃圾约积越多,为了避免OOM,G1 中还提供了另外三种垃圾回收模式:Young GC、Mixed GC 和 Full GC,它们有各自的触发条件。
Young GC: Eden区满,就会触发G1的YoungGC,对Eden区举行垃圾回收。
Mixed GC: 老年代的占用率到达了 -XX:InitiatingHeapOccupancyPercent 指定的百分比,回收所有的新生代以及部门老年代,以及大对象区。
Full GC: 在举行Mixed GC的过程中,采用的是复制算法,如果没有空的region可用,就会触发Full GC,会STW,并采用单线程来举行标记-整理算法举行GC,相当于一次Serial GC。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

老婆出轨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表