垃圾收集器

正文

本文主要介绍几种垃圾收集器。


垃圾收集器种类和关系.png

垃圾收集器

我们都知道垃圾收集算法有四种:标记-复制、标记-清除、标记-整理和分代理论。那么对应的实现有哪些了,我们意义看下它们的基本理论和优缺点。

1.1:Serial收集器(-XX:+UseSerialGC -XX:+UseSerialOldGC)

这是一个单线程收集器,优点是简单高效(与其它收集器的单线程比较),但是缺点也很明显,就是STW的时间会很长,因为只有一个线程进行垃圾收集,效率相对来说,肯定会更低。
Serial Old收集器是Serial收集器的老年版本,它同样是一个单线程收集器。它主要有两大用途:一种用途是在JDK1.5以及以前的版本中与Parallel Scavenge收集器搭配使用,另一种用途是作为CMS收集器的后备方案。
新生代采用复制算法,老年代采用标记-整理算法。

Serial收集器执行流程.png

1.2:Parallel Scavenge收集器(-XX:+UseParallelGC(年轻代),-XX:+UseParallelOldGC(老年代))

这个收集器是Serial收集器的多线程版本。它的注重点是提高吞吐量(CPU中用于运行用户代码的时间与CPU总消耗时间的比值)。CMS等其它收集器的重点是用户线程的停顿时间(提高用户体验)。
Parallel Old收集器是Parallel Scavenge收集器的老年代版本。使用多线程和“标记-整理”算法。在注重吞吐量以及CPU资源的场合,都可以优先考虑 Parallel Scavenge收集器和Parallel Old收集器(JDK8默认的新生代和老年代收集器)。
新生代采用复制算法,老年代采用标记-整理算法。

Parallel收集器执行流程.png

1.3:ParNew收集器(-XX:+UseParNewGC)

ParNew收集器其实跟Parallel收集器很类似,区别主要在于它可以和CMS收集器配合使用。
新生代采用复制算法,老年代采用标记-整理算法。
流程图和Parallel收集器一样。

1.4:CMS收集器(-XX:+UseConcMarkSweepGC(old))

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它第一次实现了垃圾收集线程与用户线程(基本上)同时工作。
通过名字中的 Mark Sweep 可以知道CMS是采用 标记-清除 算法实现的,它的实现步骤相对于前面几种也更复杂。整个过程分为四个步骤:

  • 初始标记:暂停所有的其他线程(STW),并记录下 gc roots 能直接引用的对象,速度很快。
  • 并发标记:并发标记阶段就是从GC Roots的直接关联对象开始遍历整个对象图的过程, 这个过程耗时较长但是不需要停顿用户线程, 可以与垃圾收集线程一起并发运行。因为用户程序继续运行,可能会有导致已经标记过的对象状态发生改变。
  • 重新标记:重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短。主要用到三色标记里的增量更新算法(见下面详解)做重新标记。
  • 并发清理:开启用户线程,同时GC线程开始对未标记的区域做清扫。这个阶段如果有新增对象会被标记为黑色不做任何处理(见下面三色标记算法详解)。
  • 并发重置:重置本次GC过程中的标记数据。
    CMS收集器执行流程.png

    CMS收集器的优点很明显:并发收集,低停顿。但是它的缺点也很明显:
  • 对CPU资源很敏感;
  • 无法处理浮动垃圾(在并发标记和并发清理阶段又产生垃圾,这种浮动垃圾只能等到下一次gc再清理了);
  • 它使用的回收算法-“标记-清除”算法会导致收集结束时会有大量空间碎片产生,当然通过参数-
    XX:+UseCMSCompactAtFullCollection可以让jvm在执行完标记清除后再做整理;
  • 执行过程中的不确定性,有可能发生第一次GC还没有进行完,第二次GC又开始了。特别是在并
    发标记和并发清理阶段会出现,一边回收,系统一边运行,也许没回收完就再次触发full gc,也就是"concurrent mode failure",此时会进入stop the world,用serial old垃圾收集器来回收。

三色标记

把Gcroots可达性分析遍历对象过程中遇到的对象,按照“是否访问过”这个条件标记成一下三种颜色:

  • 黑色:表示对象已经被垃圾收集器访问过, 且这个对象的所有引用都已经扫描过。 黑色的对象代表已经扫描过, 它是安全存活的, 如果有其他对象引用指向了黑色对象, 无须重新扫描一遍。 黑色对象不可能直接(不经过灰色对象) 指向某个白色对象。
  • 灰色:表示这个对象已经被垃圾收集器访问过,但这个对象上至少存在一个引用没有被扫描过。
  • 白色:表示这个对象还没有被垃圾收集器访问过。显然在可达性分析刚刚开始的阶段, 所有的对象都是白色的, 若在分析结束的阶段, 仍然是白色的对象, 即代表不可达。

多标-漏标

在并发标记阶段,因为标记期间应用线程还在运行,对象间的引用关系可能发生变化,多标和漏标的情况就有可能发生。

多标-浮动垃圾

在并发标记阶段,之前扫描过的Gcroots被销毁,这个Gcroots引用的对象又被扫描过,那么本轮GC不会回收这部分对象内存。这部分本身应该回收的内存称为浮动垃圾。但是它并不会影响垃圾回收的正确性,所以可以等到下次GC再清除。
另外,针对并发标记和并发清除阶段新增的对象,通常做法是直接指定为黑色,本轮GC不做处理。

漏标

漏标的一种可能场景:并发标记的时候,D还没有被扫描到,B指向D的引用被清除,这时候D任然是白色的,然后将D指向A的成员属性,但是因为A是黑色,不会被重新扫描,所以D还是白色,会被清除。但是这种情况是肯定不允许的,必须解决,有两种解决方案:增量更新(Incremental Update) 和原始快照(Snapshot At The Beginning,SATB) 。

漏标的可能情况.png

增量更新是指在并发标记阶段,如果黑色对象有新增白色对象的引用,会将这个引用记录下来,等到重新标记阶段,在以这个黑色对象为跟,进行重新扫描,这时候,这些白色对象就会标记成灰色或者黑色。简单理解的话,就是黑色对象一旦插入了新的白色对象引用,它就会变成灰色。
原始快照是指在清除灰色对象和白色对象的引用关系时,会将删除的引用记录下来。在并发标记结束后,会将这些白色对象直接标记为黑色,保证它们不会再本轮GC被清除。

记忆集和卡表

在可达性分析中,对于夸代引用,hotspot会使用一种叫做“卡表”(cardtable)的方式来实现记忆集来记录夸代引用关系。

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

推荐阅读更多精彩内容