精华内容
下载资源
问答
  • CMS和G1的区别

    2020-05-14 17:39:09
    CMS和G1的区别

    CMS和G1的区别

    并发的可达性分析

    三色标记:
    在遍历对象图的过程中,把访问都的对象按照"是否访问过"这个条件标记成以下三种颜色:
    
    白色:表示对象尚未被垃圾回收器访问过。显然,在可达性分析刚刚开始的阶段,所有的对象都是白色的,若在分析结束的阶段,仍然是白色的对象,即代表不可达。
    
    黑色:表示对象已经被垃圾回收器访问过,且这个对象的所有引用都已经扫描过。黑色的对象代表已经扫描过,它是安全存活的,如果有其它的对象引用指向了黑色对象,无须重新扫描一遍。黑色对象不可能直接(不经过灰色对象)指向某个白色对象。
    
    灰色:表示对象已经被垃圾回收器访问过,但这个对象至少存在一个引用还没有被扫描过。
    
    并发标记可能存在的问题:
    一种是把原本消亡的对象错误的标记为存活,这不是好事,但是其实是可以容忍的,只不过产生了一点逃过本次回收的浮动垃圾而已,下次清理就可以。
    一种是把原本存活的对象错误的标记为已消亡,这就是非常严重的后果了,一个程序还需要使用的对象被回收了,那程序肯定会因此发生错误。
    
    怎么解决第二种呢?
    产生第二种的条件当且仅当满足以下两个条件时成立:
    条件一:赋值器插入了一条或者多条从黑色对象到白色对象的新引用。
    条件二:赋值器删除了全部从灰色对象到该白色对象的直接或间接引用。
    因此有两种解决方案:
    增量更新和原始快照
    CMS是基于增量更新来做并发标记的,G1则采用的是原始快照的方式。
    
    什么是增量更新呢?
    增量更新要破坏的是第一个条件(赋值器插入了一条或者多条从黑色对象到白色对象的新引用),当黑色对象插入新的指向白色对象的引用关系时,就将这个新插入的引用记录下来,等并发扫描结束之后,再将这些记录过的引用关系中的黑色对象为根,重新扫描一次。
    可以简化的理解为:黑色对象一旦插入了指向白色对象的引用之后,它就变回了灰色对象。
    
    什么是原始快照呢?
    原始快照要破坏的是第二个条件(赋值器删除了全部从灰色对象到该白色对象的直接或间接引用),当灰色对象要删除指向白色对象的引用关系时,就将这个要删除的引用记录下来,在并发扫描结束之后,再将这些记录过的引用关系中的灰色对象为根,重新扫描一次。
    这个可以简化理解为:无论引用关系删除与否,都会按照刚刚开始扫描那一刻的对象图快照开进行搜索。
    
    展开全文
  • CMS和G1的区别是我最近在面试过程中经常被问到的一个问题,虽然能答出几点出来,但是自己并不太满意,网上关于两者的对比也没有特别完善的文章,于是打算记录下这篇文章 首先我把答案给出来,然后再去分析为什么会...

    CMS和G1的区别是我最近在面试过程中经常被问到的一个问题,虽然能答出几点出来,但是自己并不太满意,网上关于两者的对比也没有特别完善的文章,于是打算记录下这篇文章

    首先我把答案给出来,然后再去分析为什么会这样

     

    CMS

    G1

    JDK版本

    1.6以上

    1.7以上

    回收算法

    标记——清除

    标记——整理

    运行环境

    针对70G以内的堆内存

    可针对好几百G的大内存

    回收区域

    老年代

    新生代和老年代

    内存布局

    传统连续的新生代和老年代区域

    Region(将新生代和老年代切分成Region,默认一个Region 1 M,默认2048块)

    MIN_REGION_SIZE:允许的最小的REGION_SIZE,即1M,不可能比1M还小;
    MAX_REGION_SIZE:允许的最大的REGION_SIZE,即32M,不可能比32M更大;限制最大REGION_SIZE是为了考虑GC时的清理效果;

    浮动垃圾

    内存碎片

    全堆扫描

    回收时间可控

    对象进入老年代的年龄

    6

    15

    空间动态调整

    是(新生代5%-60%动态调整,一般不需求指定)

    调优参数

    多(近百个)

    少(十几个)

     

    1、CMS

    CMS(Concurrent Mark Sweep),我们可以轻易地从命名上看出,它是一个并发的,然后是基于标记——清理的垃圾回收器,它清理垃圾的步骤大致分为四步:

    1. 初始标记
    2. 并发标记
    3. 重新标记
    4. 并发清理

     

     

     (图片是出自网上,如有侵犯请联系我,谢谢)

    初始标记只要是找到GC Roots,所以是一个很快的过程,并发标记和用户线程一起,通过GC Roots找到存活的对象,重新标记主要是修复在并发标记阶段的发生了改变的对象,这个阶段会Stop the World;

    并发清理则是保留上一步骤标记出的存活对象,清理掉其他对象,正因为采用并发清理,所以在清理的过程中用户线程又会产生垃圾,而导致浮动垃圾,只能通过下次垃圾回收进行处理;

    因为cms采用的是标记清理,所以会导致内存空间不连续,从而产生内存碎片

    此处要清楚,CMS的垃圾回收的内存模型还是以我们常用的新生代,老年代的结构,如下图所示:

    2.G1

    G1(Garbage-First),以分而治之的思想将堆内存分为若干个等大的Region块,虽然还是保留了新生代,老年代的概念,但是G1主要是以Region为单位进行垃圾回收,G1的分块大体结果如下图所示:

     

    G1垃圾回收器的它清理垃圾的步骤大致分为四步:

    1. 初始标记
    2. 并发标记
    3. 最终标记
    4. 复制回收

    初始标记和并发标记和CMS的过程是差不多的,最后的筛选回收会首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划

    因为采用的标记——整理的算法,所以不会产生内存碎片,最终的回收是STW的,所以也不会有浮动垃圾,Region的区域大小是固定的,所以回收Region的时间也是可控的

    同时G1 使用了Remembered Set来避免全堆扫描,G1中每个Region都有一个与之对应的RememberedSet ,在各个 Region 上记录自家的对象被外面对象引用的情况。当进行内存回收时,在GC根节点的枚举范围中加入RememberedSet 即可保证不对全堆扫描也不会有遗漏。

    以上就是CMS和G1的对比过程,如果面试中能回答出这些内容应该就能博得面试官一笑,盗图可耻,匿了

    展开全文
  • JVM垃圾收集器CMS和G1的区别 CMS(Concurrent Mark Sweep)垃圾回收器 CMS垃圾回收原理 CMS(Concurrent Mark Sweep)收集器是一种以获取 最短回收停顿时间 为目标的收集器。采用的是"标记-清除算法",整个过程分为4步:...

    CMS(Concurrent Mark Sweep)垃圾回收器

    CMS垃圾回收原理

    CMS(Concurrent Mark Sweep)收集器是一种以获取 最短回收停顿时间 为目标的收集器。采用的是"标记-清除算法",整个过程分为4步:初始标记 => 并发标记 => 重新标记 => 并发清除,如下图所示。
    在这里插入图片描述

    由于整个过程中,并发标记和并发清除,收集器线程可以与用户线程一起工作,所以总体上来说,CMS收集器的内存回收过程是与用户线程一起并发地执行的。

    1. 初始标记:独占PUC,stop-the-world, 仅标记GCroots能直接关联的对象。
    2. 并发标记:可以和用户线程并发执行,通过GCRoots Tracing 标记所有可达对象。
    3. 重新标记:独占CPU,stop-the-world,对并发标记阶段用户线程运行产生的垃圾对象进行标记修正,以及更新自我拯救那部分逃逸对象。
    4. 并发清理:可以和用户线程并发执行,清理垃圾。

    CMS特点

    • 并发收集、低停顿。
    • 对CPU资源非常敏感: 在并发阶段虽然不会导致用户线程停顿,但是会因为占用了一部分线程使应用程序变慢。
    • 无法处理浮动垃圾(Floating Garbage):在最后一步并发清理过程中,用户线程执行也会产生垃圾,但是这部分垃圾是在标记之后,所以只有等到下一次gc的时候清理掉,这部分垃圾叫浮动垃圾。由于并发清理的时候,用户线程也在运行,就需要保证用户线程在运行的时候需要留有部分内存以供使用。但是当这部分内存不足以给用户线程正常使用时,就会出现一次 “Concurrent Mode Failure”,一旦出现了“Concurrent Mode Failure”,便会开启后备方案,临时使用SerialOld收集器进行收集工作。
    • 产生大量内存空间碎片: 当碎片过多,将会给大对象空间的分配带来很大的麻烦,往往会出现老年代还有很大的空间但无法找到足够大的连续空间来分配当前对象,不得不提前触发一次FullGC。

    G1(GarbageFirst)垃圾回收器

    G1是一个并行回收器,它把堆内存分割为很多不相关的区间,每个区间可以属于老年代或者年轻代,并且每个年龄代区间可以是物理上不连续的。
    老年代区间这个设计理念本身是为了服务于并行后台线程,这些线程的主要工作是寻找未被引用的对象,而这样就会产生一种现象,即某些区间的垃圾(未被引用对象)多于其它的区间。垃圾回收时都是需要停下应用程序的,不然就没办法防止应用程序的干扰。G1 GC可以集中精力在垃圾最多的区间上,并且只费一点点时间就可以清空这些区间的垃圾,腾出完全空闲的区间。由于这种方式的侧重点在于处理垃圾最多的区间,所以我们给G1一个名字:垃圾优先(Garbage First)。
    在这里插入图片描述

    1. 初始标记(Initial Marking):仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确可用的Region中创建新对象,这阶段需要停顿线程,但耗时很短。
    2. 并发标记(Concurrent Marking):是从GC Roots开始堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,但可与用户程序并发执行。
    3. 最终标记(Final Marking):是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程Remembered Set Logs里面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set中,这阶段需要停顿线程,但是可并行执行。
    4. 筛选回收(Live Data Counting and Evacuation):首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。这个阶段也可以做到与用户程序一起并发执行,但是因为只回收一部分Region,时间是用户可控制的,而且停顿用户线程将大幅提高收集效率。

    G1特点:

    • 并行与并发: G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU来缩短Stop-the-world停顿的时间,部分其他收集器原来需要停顿Java线程执行的GC操作,G1收集器仍然可以通过并发的方式让Java程序继续运行。
    • 分代收集: 分代概念在G1中依然得以保留。虽然G1可以不需要其它收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。也就是说G1可以自己管理新生代和老年代了。
    • 空间整合: 与CMS的标记-清除算法不同,G1从整体来看是基于标记-整理算法实现的收集器,从局部(两个Region之间)上来看是基于“复制”算法实现的。但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。
    • 可预测的停顿: 这是G1相对于CMS的一个优势,降低停顿时间是G1和CMS共同的关注点。

    CMS和G1的区别:

    特征 G1 CMS
    并发和分代
    最大化释放堆内存
    低延时
    吞吐量
    压实
    可预测性
    新生代和老年代的物理隔离
    展开全文
  • CMS和G1的区别 CMS:以获取最短回收停顿时间为目标的收集器,基于并发“标记清理”实现 过程: 1、初始标记:独占PUC,仅标记GCroots能直接关联的对象 2、并发标记:可以和用户线程并行执行,标记所有可达对象 ...

    CMS和G1的区别

    CMS 是作用于老年代 G1作用于堆

    CMS:以获取最短回收停顿时间为目标的收集器,基于并发“标记清理”实现

    过程:

    1、初始标记:独占PUC,仅标记GCroots能直接关联的对象

    2、并发标记:可以和用户线程并行执行,标记所有可达对象

    3、重新标记:独占CPU(STW),对并发标记阶段用户线程运行产生的垃圾对象进行标记修正

    4、并发清理:可以和用户线程并行执行,清理垃圾

    优点:

    并发,低停顿

    缺点:

    1、对CPU非常敏感:在并发阶段虽然不会导致用户线程停顿,但是会因为占用了一部分线程使应用程序变慢

    2、无法处理浮动垃圾:在最后一步并发清理过程中,用户县城执行也会产生垃圾,但是这部分垃圾是在标记之后,所以只有等到下一次gc的时候清理掉,这部分垃圾叫浮动垃圾

    3、CMS使用“标记-清理”法会产生大量的空间碎片,当碎片过多,将会给大对象空间的分配带来很大的麻烦,往往会出现老年代还有很大的空间但无法找到足够大的连续空间来分配当前对象,不得不提前触发一次FullGC,为了解决这个问题CMS提供了一个开关参数,用于在CMS顶不住,要进行FullGC时开启内存碎片的合并整理过程,但是内存整理的过程是无法并发的,空间碎片没有了但是停顿时间变长了

    CMS 出现FullGC的原因:

    1、年轻带晋升到老年带没有足够的连续空间,很有可能是内存碎片导致的

    2、在并发过程中JVM觉得在并发过程结束之前堆就会满,需要提前触发FullGC

     

    G1:是一款面向服务端应用的垃圾收集器

    特点:

    1、并行于并发:G1能充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短stop-The-World停顿时间。部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让java程序继续执行。

    2、分代收集:分代概念在G1中依然得以保留。虽然G1可以不需要其它收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。也就是说G1可以自己管理新生代和老年代了。

    3、空间整合:由于G1使用了独立区域(Region)概念,G1从整体来看是基于“标记-整理”算法实现收集,从局部(两个Region)上来看是基于“复制”算法实现的,但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片。

    4、可预测的停顿:这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用这明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。

     

     

    与其它收集器相比,G1变化较大的是它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留了新生代和来年代的概念,但新生代和老年代不再是物理隔离的了它们都是一部分Region(不需要连续)的集合。同时,为了避免全堆扫描,G1使用了Remembered Set来管理相关的对象引用信息。当进行内存回收时,在GC根节点的枚举范围中加入Remembered Set即可保证不对全堆扫描也不会有遗漏了。

     

    如果不计算维护Remembered Set的操作,G1收集器的运作大致可划分为以下几个步骤:

    1、初始标记(Initial Making)

    2、并发标记(Concurrent Marking)

    3、最终标记(Final Marking)

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

    看上去跟CMS收集器的运作过程有几分相似,不过确实也这样。初始阶段仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS(Next Top Mark Start)的值,让下一阶段用户程序并发运行时,能在正确可以用的Region中创建新对象,这个阶段需要停顿线程,但耗时很短。并发标记阶段是从GC Roots开始对堆中对象进行可达性分析,找出存活对象,这一阶段耗时较长但能与用户线程并发运行。而最终标记阶段需要吧Remembered Set Logs的数据合并到Remembered Set中,这阶段需要停顿线程,但可并行执行。最后筛选回收阶段首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划,这一过程同样是需要停顿线程的,但Sun公司透露这个阶段其实也可以做到并发,但考虑到停顿线程将大幅度提高收集效率,所以选择停顿。下图为G1收集器运行示意图:

     

    更加详细的介绍 请看:https://blog.csdn.net/weixin_39671217/article/details/79376100

    展开全文
  • CMS回收垃圾4个阶段CMS的总结优缺点G1回收器特点G1回收垃圾4个阶段什么情况下应该考虑使用G1G1设置参数CMS回收垃圾4个阶段初始标记并发标记重新标记并发清理初始标记阶段:会让线程全部停止,也就是 Stop ...
  • G1是把内存切分成大小相等区域(region),逻辑上把他们划分为伊甸区、幸存区、老年区。 CMS(cocurrent mark and sweep)major gc步骤: init mark:从roots出发(线程、静态引用、新生代)遍历存活对象;这个...
  • CMS:以获取最短回收停顿时间为目标收集器,基于并发“标记清理”实现 过程: 1、初始标记:独占PUC,仅标记GCroots能直接关联对象 2、并发标记:可以用户线程并行执行,标记所有可达对象 3、重新标记:...
  • java垃圾回收CMS和G1的区别

    千次阅读 2018-10-23 16:53:04
    CMS:以获取最短回收停顿时间为目标收集器,基于并发“标记清理”实现 过程: 1、初始标记:独占PUC,仅标记GCroots能直接关联对象 2、并发标记:可以用户线程并行执行,标记所有可达对象 3、重新标记:...
  • JVM垃圾回收器 CMS和G1的区别

    千次阅读 2018-12-25 17:18:50
    CMS:以获取最短回收停顿时间为目标收集器,基于并发“标记清理”实现 过程: 1、初始标记:独占PUC,仅标记GCroots能直接关联对象 2、并发标记:可以用户线程并行执行,标记所有可达对象 3、重新标记:...
  • cmsg1的区别

    2020-11-23 18:40:48
    cms回收器执行步骤 1、初始标记:GC roots 可以理解为对象指向标记 2、并发标记: GC roots Tracing 可以理解为 通过初始标记找到了要删除对象 也就是堆中指向对象 3、重新标记: 可以理解为重新执行了一遍 ...
  • G1和CMS收集器的区别

    2019-04-07 15:57:00
    G1的缺点是将内存化成了多块,所以对内存段的大小有很大的要求。 CMS是清除,所以会有很多的内存碎片。 G1是整理,所以碎片空间较小 G1和CMS都是响应优先,他们的目的都是尽量控制 stop the ...
  • G1和CMS的区别

    千次阅读 2019-09-03 00:38:21
    答案是:因为CMS作为第一款实现用户线程收集线程并发执行收集器!当时设计理念是减少停顿时间,最好是能并发执行!但是问题来了,如要用户线程也在执行,那么就不能轻易改变堆中对象内存地址!不然会导致...
  • G1和CMS区别

    2020-01-07 21:48:45
    G1和CMS区别 参考java虚拟机P84页 CMS 回收器执行步骤 1、初始标记:GC roots 可以理解为对象指向标记 2、并发标记: GC roots Tracing 可以理解为 通过初始标记找到了要删除对象 也就是堆中指向对象 3、...
  • cms重新标记和g1最终标记的区别
  • CMS收集器和G1收集器的区别

    万次阅读 2018-08-19 16:27:44
    CMS收集器和G1收集器的区别 区别一: 使用范围不一样 区别二: STW的时间 区别三: 垃圾碎片 区别四: 垃圾回收的过程不一样 对于CMS收集器和G1收集器的不同,目前简单写了一下4点,有不足的地方后面再不断的...
  • g1和cms区别

    千次阅读 2019-10-28 22:51:26
    cms回收器执行步骤 1、初始标记:GC roots 可以理解为对象指向标记 2、并发标记: GC roots Tracing 可以理解为 通过初始标记找到了要删除对象 也就是堆中指向对象 3、重新标记: 可以理解为重新执行了一遍...
  • JVM: G1和CMS的区别

    万次阅读 多人点赞 2018-12-17 12:24:12
    答案是:因为CMS作为第一款实现用户线程收集线程并发执行收集器!当时设计理念是减少停顿时间,最好是能并发执行!但是问题来了,如要用户线程也在执行,那么就不能轻易改变堆中对象内存地址!不然会导致...
  • cms收集器: 用于对老年代进行回收,目的是尽量减少应用停顿时间、减少full gc发生几率、是基于标记... 该阶段GC线程应用线程并发执行,遍历初始阶段标记出来存活对象,然后继续递归标记这些对象可达对象。...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 247
精华内容 98
关键字:

cms和g1的区别