jvm 优化篇-(8)-跨代引用问题(RememberSet、CardTable、ModUnionTable、DirtyCard)

死神-露琪亚

1、什么是跨代引用?

红色的线表示由虚拟机栈中发出的引用。显然B--->A、E--->F都是跨代引用。


跨代引用逻辑图

2、跨代引用对MonitorGC的影响

JVM GC 判断对象是否可以回收使用可达性分析的方法,可达性分析首先需要找到 GC Roots 对象。

常规GC-Root:

  • 1)虚拟机栈(栈帧中的局部变量表)中引用的对象【Stack Local】。
  • 2)本地方法栈(native方法)引用的对象。
  • 3)方法区中类静态属性、静态方法引用的对象。
  • 4)方法区中常量引用的对象。

MonitorGC个性GC-Root:

  • 5) RememberSet数据结构(CardTable是具体实现类似数组)

这里重点讲一下CardTable:
        作用:采用空间换时间,不需要扫描整个Heap空间,降低MonitorGC耗时。跨代引用带来的问题,采用CardTable很好的规避了遍历整个老年代的问题。
        HotSpot JVM的卡页(Card Page)大小为512字节,卡表(Card Table)被实现为一个简单的字节数组,即卡表的每个标记项为1个字节。

CardTable标记着是否存在老年代引用新生代

如上图发现:B、C所在的Card Page在CardTable中被标记上了。

【思考🤔】MonitorGC的GC-Root中包括CardTable,如何提高MonitorGC效率?
就需要降低跨代引用的对象,尽量设置稍大些的From、To区域,尽量将对象消灭在Young Gen区域。同时也表示对象不是越早进入老年代越好(老年代对象引用新生代对象就是一个很好的说明)!!!。

3、跨代引用对CMS中 OldGC的影响

CMS-OldGC回收♻️分为7个步骤:


CMS的7个步骤
重点步骤解读:
  • 1、初始标记(Initial Mark)

    • 目标:进行可达性分析,标记GC ROOT能直接关联到的对象。
    • 标记范围:Young Gen + Old Gen
    • 线程:JDK1.7是单线程,JDK1.8是多线程(-XX:+CMSParallelInitialMarkEnabled调整)
    • STW:触发Stop-The-World
    • 特点:速度极快
  • 2、并发标记(Concurrent Mark)

    • 目标:遍历阶段1初始标记出来的存活对象,然后继续递归标记这些对象可达的对象。(黑白灰三色标记法)。
    • 标记范围:Young Gen + Old Gen
    • STW:不触发
    • 特点:慢,很耗时。
    • 特殊操作:通过Old区卡片标记(Card Marking),提前把老年代空间逻辑划分为相等大小的区域(Card Page),如果引用关系发生改变,JVM会将发生改变的区域标记位“脏区”(Dirty Card)。JVM会对“并发标记”阶段应用线程新产生的对象及对象涉及的引用修改做记录(Mod-Union Table)
  • 3、预清理(Preclean)

    • 目标:2阶段中记录在Mod-Union Table的这些脏区会被找出来,刷新引用关系,清除“脏区”标记。
    • 标记范围: Old Gen。
    • 线程:GC线程和应用线程也是并发执行
    • STW:不触发
    • 特点:速度一般
  • 4、可中断的预清理(Concurrent Abortable Preclean)

    • 目标:降低垃圾回收时对应用的暂停时间,整个过程最耗时步骤在5(最终标记),所以4步骤提前进行。
    • 触发条件:此阶段在Eden区使用超过2M时启动,当然2M是默认的阈值,可以通过参数修改。
    • 标记范围:Young Gen + Old Gen
      • 处理From、To区对象,标记可达到老年代的对象。
      • 和3阶段一样,扫描处理Dirty Card中的对象。
    • 终止逻辑:CMS为了避免这个阶段没有等到Minor GC而陷入无限等待,提供了参数CMSMaxAbortablePrecleanTime ,默认为5s,含义是如果可中断的预清理执行超过5s,不管发没发生Minor GC,都会中止此阶段,进入Remark。
    • 线程:GC线程和应用线程也是并发执行。
    • STW:不触发
    • 特点:速度一般
    • 特殊:下一个阶段要执行最耗时且STW的Remark阶段,Remark阶段会将整个YoungGen作为GC-Root进行操作,如果4阶段能触发一次MonitorGC就再好不过了。
  • 5、重新标记(Final ReMark)

    • 目标:GC事件中第二次(也是最后一次)STW阶段,目的是完成老年代中所有存活对象的标记。
    • 标记范围:Young Gen + Old Gen
    • 线程:GC线程独占执行
    • STW:触发Stop-The-World
    • 特点:速度较慢,可以说是整个CMS-Old GC的瓶颈点
    • 特殊:
      • 1、遍历新生代对象,重新标记
      • 2、根据GC Roots,重新标记
      • 3、遍历老年代的Dirty Card,重新标记
  • 6、并发清除(Concurrent Sweep)

    • 目标:根据标记结果清除垃圾对象。
    • 标记范围:Old Gen。
    • 线程:GC线程和应用线程也是并发执行
    • STW:不触发
    • 特点:速度一般。
  • 7、并发重置(Concurrent Reset)

    • 目标:重置CMS算法相关的内部数据, 为下一次GC循环做准备。
    • 线程:GC线程和应用线程也是并发执行
    • STW:不触发
    • 特点:速度一般。
7步图解:
三阶段:初始标记

二阶段:并发标记

三阶段:并发预清理

六阶段:并发清除

4、问题思考🤔:

【思考🤔】CMS oldgc中remark耗时问题,跨代引用是图一中的B--->A 还是 E--->F?
答案:E--->F。
通过:-XX:+CMSScavengeBeforeRemark ,触发MonitorGC降低的就是YoungGen区的对象,从而达到标记源头减少,降低remark时间。
【思考🤔】CMS 跨代引用是图一中的B--->A 有何危害,虚拟机是如何避开的?
答案:CardTable。
逻辑:采用创建CardTable空间区域,来避免扫整个老年代。当B无引用的时候,cardTable会被标记,一次MonitorGC就会回收♻️掉。B是如何做到没引用的,同E--->F是一样的逻辑。

【思考🤔】CMS里有两个需要STW的阶段:initial mark,remark、这两个标记有什么不一样么?使用的GC-Root一样么?
答案:不一样。
初始标记:使用的是常规的GC-Root(虚拟机栈栈帧中的局部变量表、本地方法栈native方法、方法区中类的静态属性和方法、方法区中常量等引用的对象)
重新标记:

  • 常规的GC-Root。(只有MonitorGC才会使用跟可达分析)
  • 新生代所有对象。
  • 遍历老年代的DirtyCard(ModUnionTable)。

【思考🤔】同时带来了另外一个问题,MonitorGC可没有遍历整个老年代,而是采用CardTable通过时间换空间的做法,CMS-OldGC为什么采用遍历新生代所有的对象呢?
        这就是YoungGen 与 OldGen存在明显的差异:

  • 老年代对象都是经历过多次GC回收♻️存活下来了,对象存在的变数极低。所以采用空间换时间效果较好。
  • 新生代对象属于变化特别快的区域,如果采用空间换时间,既浪费了空间,也没有提升性能。

【思考🤔】既然initial mark阶段+concurrent mark阶段已经扫果了young gen 为何还要再次Remark?

【思考🤔】CardTable与mod-union table有什么关系,都是干什么的?

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