垃圾收集器

一、CMS收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。大部分应用在浏览器的B/S系统的服务端上

收集步骤:
    1. 初始标记(CMS initial mark)
      仅仅只是标记GC Roots能够直接关联到的对象,速度快
    1. 并发标记(CMS concurrent mark)
      从GC Roots的直接关联对象开始边遍历整个对象图的过程。速度快,不需要停顿用户线程,与垃圾收集线程并发执行
    1. 重新标记(CMS remark)
      修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,停顿时间较长。
    1. 并发清除(CMS concurrent sweep)
      清理删除掉标记阶段判断已经死亡的对象,由于不需要移动存活对象,这阶段是可以与用户线程同时并发的。

其中初始标记、重新标记仍然需要“Stop The World”

缺点:

1、CMS对处理器资源非常敏感。在并发阶段,虽然不会导致用户线程停顿,但却会占用一部分线程,导致应用程序变慢,降低吞吐量

2、在CMS的并发标记和并发清除阶段,用户线程还在继续运行,程序在运行自然还会伴随有新的垃圾对象不断产生,但这一部分垃圾对象是出现在标记过程结束以后,这部分称为“浮动垃圾(Floating Garbage)”
CMS收集器无法处理“浮动垃圾”,有可能出现“Con-current Mode Failure”失败而导致另一次完全的“Stop The World”的Full GC产生。

3、由于CMS是基于“标记-清除”算法实现的收集器,这也就意味着收集结束时会有大量空间碎片产品,也将会给大对象分配带来很大麻烦,往往会出现老年代还有很多剩余空间,但就是无法找到足够大的连续空间来分配当前对象,不得不提前触发一次Full GC。

二、Garbage First收集器(简称G1)

它是一个面向局部收集的设计思路和基于Region的内存布局形式。是主要面向服务端应用的垃圾收集器。在JDK 8 update 40后,G1收集器才被Oracle官方称为“全功能的垃圾收集器(Fully-Featured Garbage Collector)”

在G1收集器出现之前所有的其他收集器,包括CMS在内,垃圾收集的目标要么是整个新生代(Minor GC),要么是整个老年代(Major GC),要么就是整个Java堆(Full GC)。而G1则是面向堆内存任何部分组成回收集(Collection Set,简称CSet)进行回收,衡量标准不再是属于哪个分代,而是哪块内存中存放的垃圾数量最多,回收收益最大,这就是G1收集器的Mixed GC模式。

G1是把连续的Java堆划分为多个大小相等的独立区域(Region),每个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间或者老年代空间,收集器能够扮演不同角色的Region采用不同的策略去处理,这样无论新创建的对象还是已经存活了一段时间、熬过多次收集的旧对象都能获得很好的收集效果。

Region中还有一类特殊的Humongous区域,专门用来存储大对象。G1中的新生代和老年代不再是固定的,他们都是一系列区域(不需要连续)的动态集。G1将Region作为单次回收的最小单元,每次收集到的内存空间都是Region大小的整数倍,这样有计划的避免在整个Java堆中进行区域的垃圾收集。G1收集器会跟踪各个Region里面的垃圾堆的“价值”大小,然后在后台维护一个优先级列表,优先回收收益最大的哪些Region,这也是“Garbage First”名字的由来。这样在有限的时间内尽可能高的收集效率。

如何解决Region中存在跨Region引用对象?

使用记忆集避免全堆作为GC Roots扫描。每个Region都有自己的记忆集,这些记忆集会记录下别的Region指向自己的指针,并标记这些指针分别在哪些卡页的范围之内。
G1记忆集在存储结构上本质是一种哈希表,Key是别的Region的起始地址,Value是一个集合,里面存储的元素是卡表的索引号。它是一种双向卡表(相互指向)。
G1收集器占用更高的内存负担,G1至少要耗费大约相当于Java堆容量的10%至20%的额外内存来维持收集器工作。

在并发阶段如何保证收集线程与用户线程互不干扰地运行?

CMS收集器采用增量更新算法实现,而G1收集器则是通过原始快照(SATB)算法来实现。
垃圾收集对用户线程的影响还体现在回收过程中新创建对象的内存分配上。G1为每一个Region设计了两个名为TAMS(Top at Mark Start)的指针,把Region中的一部分空间划分出来用于并发回收过程中的新对象分配,并发回收时新分配的对象地址都必须要在两个指针位置以上。
G1收集器则是默认被隐式标记过的,默认他们时存活的,不纳入回收范围。
CMS中的“Concurrent Mode Failure”失败会导致Full GC类似。如果内存回收的速度赶不上内存分配的速度,G1收集器也要被迫冻结用户线程执行,导致“Full GC”而产生长时间的“Stop The World”

怎样建立起可靠的停顿预测模型?

用户通过-XX:MaxGCPauseMillis参数指定的停顿时间意味着垃圾收集发生之前的期望值。
G1收集器怎么做到才能满足用户的期望值呢?
G1收集器的停顿预测模型是以衰减均值(Decaying Average)为理论基础来实现的。
在垃圾收集过程中,G1收集器会记录每个Region的回收耗时、每个Region记忆集里的脏卡数量等各个可测量的步骤花费的成本,并分析出平均值、标准偏差、置信度等统计信息。

G1收集器运行过程
  • 初始标记(Initial Marking)
    仅仅是标记GC Roots能直接关联到的对象,并且修改TAMS指针的值,让下一阶段用户线程并发运行时,能够正确地在可用的Region中分配新对象。这个阶段需要停顿现场,但是耗时短,并且还是借用Minor GC的时候同步完成,所以G1收集器在这个阶段并没有额外的停顿。
  • 并发标记(Concurrent Marking)
    从GC Roots开始对堆中对象进行可达性分析,递归扫描整个堆中的对象图,找出要回收的对象,这个耗时较长,但可与用户程序并发执行。当对象图扫描完成以后,还要重新处理SATB记录下的并发时有引用变动的对象。
  • 最终标记(Final Marking)
    对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录
  • 筛选回收(Live Data Counting and Evacuation)
    负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region构成回收集,然后把决定回收的那一部分Region的存活对象复制到空Region 中,再清理掉整个旧Region的全部空间。这里的操作涉及存活对象的移动,是必须暂定用户线程,由多条收集器线程并行完成的。

从上述描述可以看出,G1收集器除了并发标记外,其余阶段也是要完全暂停用户线程的。

总的来说,在小内存应用上CMS表现大概率仍然优于G1,而在大内存应用上G1大多能发挥其优势

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352