第六章 JVM垃圾收集器(2)

上一章记录了几种常见的垃圾收集器,见《第五章 JVM垃圾收集器(1)

1、G1

说明:

  • 从上图来看,G1与CMS相比,仅在最后的"筛选回收"部分不同(CMS是并发清除),实际上G1回收器的整个堆内存的划分都与其他收集器不同。
  • CMS需要配合ParNew,G1可单独回收整个空间

原理:

  • G1收集器将整个堆划分为多个大小相等的Region
  • G1跟踪各个region里面的垃圾堆积的价值(回收后所获得的空间大小以及回收所需时间长短的经验值),在后台维护一张优先列表,每次根据允许的收集时间,优先回收价值最大的region,这种思路:在指定的时间内,扫描部分最有价值的region(而不是扫描整个堆内存),并回收,做到尽可能的在有限的时间内获取尽可能高的收集效率。

运作流程:

  • 初始标记:标记出所有与根节点直接关联引用对象。需要STW
  • 并发标记:遍历之前标记到的关联节点,继续向下标记所有存活节点。
    • 在此期间所有变化引用关系的对象,都会被记录在Remember Set Logs中
  • 最终标记:标记在并发标记期间,新产生的垃圾。需要STW
  • 筛选回收:根据用户指定的期望回收时间回收价值较大的对象(看"原理"第二条)。需要STW

优点:

  • 停顿时间可以预测:我们指定时间,在指定时间内只回收部分价值最大的空间,而CMS需要扫描整个年老代,无法预测停顿时间
  • 无内存碎片:垃圾回收后会整合空间,CMS采用"标记-清理"算法,存在内存碎片
  • 筛选回收阶段:
    • 由于只回收部分region,所以STW时间我们可控,所以不需要与用户线程并发争抢CPU资源,而CMS并发清理需要占据一部分的CPU,会降低吞吐量。
    • 由于STW,所以不会产生"浮动垃圾"(即CMS在并发清理阶段产生的无法回收的垃圾)

适用范围:

  • 追求STW短:若ParNew/CMS用的挺好,就用这个;若不符合,用G1
  • 追求吞吐量:用Parallel Scavenge/Parallel Old,而G1在吞吐量方面没有优势

2、几点注意

问题1、G1以外的其他收集器在回收垃圾的时候:要不只是扫描年轻代,要不只是扫描年老代。在年轻代的回收过程中,如果旧生代中的对象引用了年轻代的对象,那么我们只扫描年轻代就不行了,但是由于年老代一般而言是年轻代的3倍大小,如果年轻代、年老代一起去扫描的话,效率会急剧下降,这个问题怎么处理?

:JVM采用remember set来做的这个事儿,当发现一个引用对象被赋值时,JVM发出一个write barrier指令来暂时中断写操作,检查被赋值的引用对象是不是处于年老代,且其引用的对象是不是处于新生代(即是不是年老代对象引用了年轻代对象),如果是,将相关引用信息记录到remember set。之后的扫描,我们会从根集合+remember set向下进行扫描。(也就是说真正的根集合,是JVM定义的根集合+remember set)

问题2、G1收集器为了做到GC时间可预测,采用扫描部分价值最大的region来实现,那么如果这部分region中的对象被其他region中的对象所引用,那么仅扫描前者可能就不行了,但是如果扫描全部region的话,又无法做到GC时间可预测,效率会大大下降,怎么办?

:G1同理,为每一个region分配一个remember set,当发现一个引用对象被赋值时,JVM发出一个write barrier指令来暂时中断写操作,检查被赋值的引用对象与其引用的对象是不是处于不同的region(eg.a=b;检查a与b是不是在不同的region),如果是,将相关引用信息记录到当前region的remember set。之后的扫描,我们会从根集合+remember set向下进行扫描。

问题3、CMS与G1在并发标记的时候若发部分引用对象的引用关系发生了变化,怎么处理才能让重新标记的时候仅仅扫描出这些变化?

:在并发标记期间,对象的引用关系若发生了变化,这些相关的记录就会记录到remember set logs;在重新标记阶段,将该logs的信息加入到remember set中去,然后再从remember set去向下trace节点。

时间: 2024-11-04 17:44:54

第六章 JVM垃圾收集器(2)的相关文章

JVM垃圾收集器(1)

此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法> 1.七种垃圾收集器 Serial(串行GC)-- 复制 ParNew(并行GC)-- 复制 Parallel Scavenge(并行回收GC)-- 复制 Serial Old(MSC)(串行GC)-- 标记-整理 CMS(并发GC)-- 标记-清除 Parallel Old(并行GC)--标记-整理

5种JVM垃圾收集器特点和8种JVM内存溢出原因

先来看看5种JVM垃圾收集器特点 一.常见垃圾收集器 现在常见的垃圾收集器有如下几种: 新生代收集器: Serial ParNew Parallel Scavenge 老年代收集器: Serial Old CMS Parallel Old 堆内存垃圾收集器:G1 每种垃圾收集器之间有连线,表示他们可以搭配使用. 二.新生代垃圾收集器 (1)Serial 收集器 Serial 是一款用于新生代的单线程收集器,采用复制算法进行垃圾收集.Serial 进行垃圾收集时,不仅只用一条线程执行垃圾收集工作,

JVM垃圾收集器

1.垃圾回收器类型 1.串行垃圾回收器(Serial Garbage Collector) 2. 并行垃圾回收器(Parallel Garbage Collector) 3. 并发标记扫描垃圾回收器(CMS Garbage Collector) 4. G1垃圾回收器(G1 Garbage Collector) 1.串行垃圾回收器(Serial Garbage Collector) 串行垃圾回收器通过持有应用程序所有的线程进行工作.它为单线程环境设计,只使用一个单独的线程进行垃圾的回收,通过冻结所

【006】【JVM——垃圾收集器总结】

 JVM--垃圾收集器总结 垃圾收集器概览 收集算法是内存回收的方法论,垃圾收集据是内存回收的具体实现.Java虚拟机规范中对垃圾收集器应该如何实现没有规定,不同的厂商.不同版本的虚拟机所提供的垃圾收集器可能会有很大差别,一般都会提供参数供用户根据自己的所用特点和要求组合出各个年代所使用的收集器.下面是基于JDK 1.7 Update 14 之后的HotSpot 虚拟机垃圾收集器.如果两个收集器之间有连线就说明它们可以搭配使用.直到现在还没有最好的收集器,更加设有万能的收集器,只是对具体应用

JVM垃圾收集器-Parallel Scavenge收集器

今天我给大家讲讲JVM垃圾收集器-Parallel Scavenge收集器 Parallel Scavenge收集器 ? ? ? ?Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器,看上去和ParNew都一样,那它有什么特别之处呢? ? ? ??Parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标是

记一次有关于Jvm垃圾收集器的整理

记一次有关于Jvm垃圾收集器的整理 垃圾回收器 算法: 引用计数法 复制算法 标记清楚 标记整理 垃圾回收的方式 1.Serial:串行回收 2.Parallel:并行回收 3.CMS:并发标记清除 4.G1:G1 截止到java10               之后有ZGC Seial:串行垃圾回收,单线程垃圾回收的时候会停掉用户的线程进行垃圾回收不适合服务器的环境 Parallel:并行垃圾回收多个垃圾收集线程并行工作也会停掉垃圾回收的时候用户的线程 CMS:用户线程和垃圾回收线程同时执行(

jvm 垃圾收集器分析

jvm 垃圾收集器分析 jvm 垃圾收集器分析   新生代收集器 老年代收集器 优点 缺点 serial收集器 V   1.jdk1.3开始的单线程收集器 2.client模式下很好的选择. 3.复制算法 1.单线程,收集时需要暂停所有线程(stop the world) parNew收集器 V   1.serial的多线程版 2.server模式下 3.可与CMS收集器工作 4.线程数与cpu数相同 1.单CPU下不会比serial收集器性能好   Parallel Scavenge 收集器

深入了解JVM垃圾收集器

程序计数器.JVM栈.本地方法栈这三个内存区域和线程是一一对应的,并且每一个线程的这三个区域相互独立互不干扰.他们都随着线程的产生而产生,线程的灭亡而灭亡.JVM栈和本地方法栈中的栈帧都随着方法的加载而入栈,随着方法的结束而出栈. 栈帧的大小是在程序员写类的时候就确定下来的.因此这三种区域的内存大小都具备确定性,当方法结束或线程结束后,这些内存空间就会自动被回收掉,所以JVM无需考虑这些区域的内存回收问题. 堆内存和方法区的内存分配和回收就不一样了,因为一个接口中的多个实现类所需要的内存可能不一

【JVM】JVM垃圾收集器、垃圾收集算法、无用对象

Java 常见的垃圾收集器有哪些 实际上,垃圾收集器(GC,Garbage Collector)是和具体 JVM 实现紧密相关的,不同厂商(IBM.Oracle),不同版本的JVM,提供的选择也不同.接下来,我来谈谈最主流的 Oracle JDK. Serial GC 它是最古老的垃圾收集器,"Serial"体现在其收集工作是单线程的,并且在进 行垃圾收集过程中,会进入臭名昭著的"Stop-The-World"状态.当然,其单线程设计也意味着精简的 GC 实现,无需