JVM虚拟机垃圾回收CMS和G1的区别

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

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

 

CMS

G1

JDK版本

1.6以上

1.7以上

回收算法

标记——清除

标记——整理

运行环境

针对70G以内的堆内存

可针对好几百G的大内存

回收区域

老年代

新生代和老年代

内存布局

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

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

浮动垃圾

内存碎片

全堆扫描

回收时间可控

对象进入老年代的年龄

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的对比过程,如果面试中能回答出这些内容应该就能博得面试官一笑,盗图可耻,匿了

发布了6 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tushuping/article/details/103927644
今日推荐