范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

JVM面试必问的CMS,你懂了吗?

  前言
  虽然 CMS 已经是很古老的垃圾回收器了,大家现在动不动就G1、ZGC啥的,但是据我所了解,还是有很多公司的生产环境主要使用的 CMS,包括我自己呆过的几家大厂也是。
  因此在 JVM 面试中,CMS 也是问的最多的,包括我自己现在面试别人时,问到 JVM 这一块,我也喜欢从CMS开始,逐渐深入。
  不多废话,今天我们就来盘他。
  正文
  1、什么是卡表(card table)?
  试想一下,在进行 YGC 时,如何判断是否存在老年代到新生代的引用?
  一个简单的办法是扫描整个老年代,但是这个代价太大了,因此 JVM 引入了卡表来解决这个问题。
  卡表又称为卡片标记(card marking),由 Paul R. Wilson 和 Thomas G. Moher 在1989年发表的论文里提出。
  其原理为,在逻辑上将老年代空间分割为若干个固定大小的连续区域,分割出来的每一个个区域就称为卡片(card)。另外,为每个卡片准备一个与其对应的标记位,最简单的实现方案是由字节数组实现,以卡的编号作为索引。每个卡的大小通常介于128~512字节之间,一般使用2的幂字节大小,例如HotSpot使用512字节。
  当卡片内部发生引用变化时(指针写操作),写屏障会将该卡在卡表中对应的字节标记为脏(dirty)。
  有了卡表后,在 YGC 时,只需将卡表中被标记为 dirty 的 card 也作为扫描范围,就可以保障不扫描整个老年代也不会有遗漏了。
  2、什么是 mod-union table?
  通过上面对 card table 的介绍,我们知道 card table 会记录下老年代所有发生过引用变化对象所在的 card,而 CMS 在并发标记等阶段,也需要记录下老年代发生引用变化的对象以便后续重新扫描,是否可以直接复用 card table?
  答案是不行的,这是因为每次 YGC 过程中都涉及重置和重新扫描 card table,这样是满足了 YGC 的需求,但却破坏了CMS的需求,CMS 需要的信息可能被 YGC 给重置掉了。为了避免丢失信息,于是在 card table 之外另外加了一个 Bitmap 叫做 mod-union table。
  在 CMS 并发标记正在运行的过程中,每当发生一次 YGC,当 YGC 要重置 card table 里的某个记录时,就会更新 mod-union table 对应的 bit,相当于将 card table 里的信息转移到了 mod-union table 里。
  这样,最后到 Final remark 的时候,card table 加 mod-union table 就足以记录在并发标记过程中老年代发生的所有引用变化了。
  3、CMS 垃圾收集的过程?
  CMS 垃圾收集的过程网上通常有两个版本,4个步骤的和7个步骤的,两个版本其实都是对的。
  4个步骤应该主要是跟随周志明的说法,而 CMS 的相关论文其实也是按4个步骤介绍。
  7个步骤则应该更多是从 CMS 的日志得出的说法,而7个步骤里其实也包含了上述的4个步骤,可以理解为7个步骤是更细的说法。
  个人而言,我会更喜欢7个步骤的说法,因此这边介绍下7个步骤的过程。
  1)初始标记(Initial Mark)
  STW(stop the world),遍历 GC Roots,标记 GC Root 直达的对象。
  2)并发标记(Concurrent Mark)
  从初始标记阶段被标记为存活的对象作为起点,向下遍历,找出所有存活的对象。
  同时,由于该阶段是用户线程和GC线程并发执行,对象之间的引用关系在不断发生变化,对于这些对象,都是需要进行重新标记的,否则就会出现错误。为了提升重新标记的效率,JVM 会使用写屏障(write barrier)将发生引用关系变化的对象所在的区域对应的 card 标记为 dirty,后续只需要扫描这些 dirty card 区域即可,避免扫描整个老年代。
  3)并发预处理(Concurrent Preclean)
  该阶段存在的意义主要是为了尽可能降低 Final Remark 阶段的耗时,因为 Final Remark 阶段是 STW 的。
  该阶段主要做的事是将上一阶段被标记为 dirty 的 card 所对应的区域进行重新扫描标记,处理并发阶段发生引用变化的对象。
  4)可中断的并发预处理(Concurrent Abortable Preclean)
  该阶段和并发预处理做的事是基本一样的,也是主要处理 dirty card。区别在于并发预处理只执行一次,而本阶段会一直循环执行,直到触发终止条件。
  终止条件有以下几个:  循环次数超过阈值 CMSMaxAbortablePrecleanLoops,默认是0,也就是没有循环次数的限制。  处理时间达到了阈值 CMSMaxAbortablePrecleanTime,默认是5秒。  Eden区的内存使用率达到了阈值 CMSScheduleRemarkEdenPenetration,默认为50%。
  同时该阶段有一个触发前提:  Eden 区的内存使用量大于参数CMSScheduleRemarkEdenSizeThreshold,默认是2M。
  5)最终标记/重新标记(Final Remark)
  STW(stop the world),主要做两件事:  遍历 GCRoots,重新扫描标记  遍历被标记为 dirty 的 card,重新扫描标记
  6)并发清理(Concurrent Sweep)
  清理未使用的对象并回收它们占用的空间。
  7)并发重置(Concurrent Reset)
  重置 CMS 算法用于打标的数据结构(markBitMap),为下一次收集做准备。
  4、CMS存在的问题
  1)使用的标记-清除算法,可能存在大量空间碎片。
  调优:开启CMS压缩,查看参数是否合理。  // 开启CMS压缩,在FGC时执行压缩,默认为true -XX:+UseCMSCompactAtFullCollection  // 执行几次FGC才执行压缩,默认为0 -XX:CMSFullGCsBeforeCompaction=0
  2)并发清理可能出现"Concurrent Mode Failure"失败而导致另一次Full GC的产生
  调优:可能是触发GC的比例太高,适当调低该值。  // CMS触发GC的比例 -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSInitiatingOccupancyFraction=70
  3)对CPU资源非常敏感。在并发阶段,会因为占用了一部分线程(或者说CPU资源)而导致应用程序变慢,总吞吐量会降低。CMS默认启动的回收线程数是(CPU数量+3)/4。
  调优:可能是并发线程数设置太高,适当调低该值。  // CMS并发线程数 -XX:ConcGCThreads=X
  以上的调优只是针对一些可能性较大的问题给的建议,具体还是需要结合场景和完整的JVM参数去分析,各个参数可能都会影响到整体的GC效率。
  5、Final Remark 阶段为什么还需要遍历 GCRoots?
  这是因为 CMS 的写屏障(write barrier)并不是对所有会导致引用变化的字节码生效,例如不支持  astor  e_X(把栈顶的值存到本地变量表)。
  至于为什么不为 astore_X 添加写屏障,R 大认为是栈和年轻代属于数据快速变化的区域,对于这些区域使用写屏障的收益比较差。
  6、Final Remark 阶段还需要遍历 GC Roots,那之前的标记工作不是白做了?
  不是的。
  在三色标记法中(见下面介绍),如果扫描到被标记为黑色的对象就会终止,而之前的并发标记和预处理已经完成了绝大部分对象的标记,也就是此时大部分对象已经是黑色了,因此 Final Remark 阶段的工作其实会减少很多。简单来说就是:遍历的广度不变,但是深度变浅了。
  7、三色标记算法?
  三色标记算法由 Edsger W. Dijkstra 等人在1978年提出,是一种增量式垃圾回收算法,增量式的意思是慢慢发生变化的意思,也就是 GC 和 mutator(应用程序)一点点交替运行的手法。
  与其相反的则是停止型GC,也就是GC时,mutator 完全停止,GC结束再恢复运行。  三色标记算法顾名思义就是将 GC 中的对象分为三种颜色,这三种颜色和所包含的意思如下:白色:还未搜索过的对象。在回收周期的开始阶段,所有对象都为白色,而在回收周期结束时,所有白色对象均为不可达对象,也就是要回收的对象。
  灰色:正在搜索的对象。已经被搜索过的对象,但是该对象引用的对象还未被全部搜索完毕。
  黑色:搜索完成的对象。本身及其引用的所有对象都被搜索过,黑色对象不会指向白色对象,同时黑色对象不会被重新搜索,除非颜色发生变化。
  我们以 GC 标记-清除算法为例简单的说明一下。
  GC 开始运行前所有的对象都是白色。GC 一开始运行,所有从根能到达的对象都会被标记为灰色,然后被放到栈里。GC 只是发现了这样的对象,但还没有搜索完它们,所以这些对象就成了灰色对象。
  灰色对象会被依次从栈中取出,其子对象也会被涂成灰色。当其所有的子对象都被涂成灰色时,该对象就会被涂成黑色。当 GC 结束时已经不存在灰色对象了,活动对象全部为黑色,垃圾则为白色。
  下面是一个三色标记算法的示例动图,大家参考着理解。
  明白了三色标记算法后,再回过头去看第5题,是不是顿时就明白了。
  8、三色标记算法存在的问题?
  三色标记算法是增量式垃圾回收算法,mutator可能会随时改变对象引用关系,因此在并发下会存在漏标和错标(多标)。
  1)漏标
  直接通过一个简单的例子来看:
  假设当GC线程执行到时刻1时,此时应用线程先执行了步骤1和2,也就是到了时刻3的场景,GC线程继续执行。
  此时对象Z只被黑色对象X所引用,而黑色对象是不会被继续扫描的,因此扫描结束后Z仍然是白色对象,也就是时刻4,此时白色对象Z则会被当做垃圾而回收。
  2)错标(多标)
  直接通过一个简单的例子来看:
  假设当GC线程执行到时刻1时,此时应用线程先执行了步骤1,也就是到了时刻2的场景,GC线程继续执行。
  此时对象Z是灰色对象,GC线程对其进行搜索,搜索结束后将其标记为黑色,也就是时刻3,此时对象Z其实没有到GC Roots的引用,理应被回收,但是因为被错误的标记为黑色,而在本次GC中存活了下来。
  错标和漏标都是三色标记算法存在的问题,但是两者带来的后果有本质的不同。
  错标使得死亡的对象被当做存活,导致出现浮动垃圾,此时不影响程序的正确性,这些对象下次GC时回收就可以了。
  漏标使得存活的对象被当做死亡,这个会导致程序出错,带来不可预知的后果,这个是不能接受的,因此漏标是三色标记算法需要解决的问题。
  通过实验追踪,Wilson 发现,只有当以下两个条件同时满足时才会出现漏标问题:
  1)将某一指向白色对象的引用写入黑色对象
  2)从灰色对象出发,最终到达该白色对象的所有路径都被破坏
  9、增量更新和起始快照
  为了解决三色标记算法的漏标问题,产生了两种比较著名的解决方案:增量更新和起始快照,CMS 和 G1 就是采用了这两种解决方案,CMS 使用的增量更新,G1使用的起始快照。
  漏标问题的出现必须同时满足上述的两个条件,因此解决办法只需破坏两个条件之一即可。
  1)增量更新(Incremental update)
  使用写屏障(write barrier)拦截所有新插入的引用关系,将其记录下来,最后以这些引用关系的源头作为根,重新扫描一遍即可解决漏标问题。
  增量更新破坏的是条件1,当插入黑色对象到白色对象的引用时,写屏障会记录下该引用,后续重新扫描。
  以上面的漏标为例,就是拦截步骤1:X.b=Y.a,记录下X,然后重新扫描对象X。
  2)起始快照(SATB,snapshot at the begin)
  使用写屏障拦截所有删除的引用关系,将其记录下来,然后将被删除的引用关系所指向的对象会被当作存活对象(非白色),重新扫描该对象。
  SATB 抽象的说就是在一次GC开始时刻是存活的对象,则在本次GC中都会被当做存活对象,此时的对象形成一个逻辑"快照",这也是起始快照名字的由来。
  起始快照破坏的是条件2,当到白色对象的引用断开时,写屏障会记录下该引用,将该对象当作存活对象,后续继续扫描该对象的引用。
  以上面的漏标为例,就是拦截步骤2:Y.a=null,将Z作为存活对象,然后重新扫描对象Z。
  10、CMS中的 Final Remark(重新标记)阶段⽐较慢,怎么分析和解决?
  CMS 的整个垃圾回收过程中只有2个阶段是 stop the world,一个是初始标记,一个是重新标记,初始标记只标记GC Roots直达的对象,因此一般不会耗时太久,而重新标记出现耗时久的现象则比较多见,通常如果CMS GC较慢,大多都是重新标记阶段较慢导致的。
  Final Remark 阶段比较慢,比较常见的原因是在并发处理阶段引用关系变化很频繁,导致 dirty card 很多、年轻代对象很多。
  比较常见的做法可以在 Final Remark 阶段前进行一次 YGC,这样年轻代的剩余待标记对象会下降很多,被视为GC Root 的对象数量骤减, Final Remark 的工作量就少了很多。  // 在remark之前尝试进行清理,默认值为false  -XX:+CMSScavengeBeforeRemark
  通常增加 -XX:+CMSScavengeBeforeRemark 都能解决问题,但是如果优化后还是耗时严重,则需要进一步看具体是哪个小阶段耗时严重。
  Final Remark 具体包含了若干个小阶段:weak refs processing、class unloading、scrub string table等,从日志里可以看出来每个小阶段的耗时,根据耗时的阶段再进行针对性的分析,可以查阅源码或者查阅相关资料来帮助分析。
  以比较常见的 weak refs processing 为例:
  这边的 weak refs 不是单指 WeakReference,而是包括了:SoftReference、WeakReference、FinalReference、PhantomReference、JNI Weak Reference,这边应该是除了强引用外的所有引用都被归类为 weak 了。
  因此,我们首先添加以下配置,打印出GC期间引用相关更详细的日志。  // 打印GC的详细信息 -XX:+PrintGCDetails  // 打印在GC期间处理引用对象的时间(仅在PrintGCDetails时启用)  -XX:+PrintReferenceGC
  然后根据每个引用的耗时,定位出耗时严重的引用类型,然后查看项目中是否存在对该引用类型不合理的使用。
  另外一种比较简单粗暴的办法是可以通过增加引用的并行处理来尝试解决,通常会有不错的效果。   // 启用并行引用处理,默认值为false -XX:+ParallelRefProcEnabled
  而如果是 scrub string table 阶段耗时,则可以分析项目中是否存在不合理的使用 interned string,其他的也类似。  原文链接:https://mp.weixin.qq.com/s/SOPhw_HxPNscIMuQqFaRIA
  原作者:程序员囧辉

架构实战基于条件配置的简单规则引擎实现规则引擎是大型系统必不可少的一个组件,基于规则引擎可以实现灵活的规则和控制功能。本文从需求出发,介绍了一种简单且高效的实现规则引擎的方案。第一章需求概述规则引擎的应用可以说非常的广南卡RunnerPro2评测,好音质轻佩戴,耳朵敏感的最优解在当下,TWS真无线蓝牙耳机似乎已经成了潮流青年的标配,但是,也有少数耳朵敏感的小伙伴却在佩戴蓝牙耳机时遇到了问题,有的是因为耳洞小,找不到合适的耳塞,戴上入耳式得耳机会把耳道撑得冬日暖心好物飞乐思发热围巾,3秒速热驱寒保暖一到冬天,我们就会裹上厚厚的衣服,不过,凛冽的寒风总是无孔不入,它还会从你的脖子钻进身体,要想裹得严实一点,还需要一条围巾来御寒。这次非常荣幸,我在亿智蘑菇试用活动中获得了飞乐思发从地面到大气层距离有多少公里?从广义上来说,地球的大气层其实非常厚,其厚度可能要比地球半径还大。根据高度的不同,地球大气层可以分为很多层。对流层我们生活在大气层最底端,这里是对流层,其厚度约为12公里。这层拥有在俄罗斯国产品牌真我(Realme)将把苹果手机挤出市场前三名俄罗斯卫星通讯社莫斯科11月23日电生意人报报道称,中国生产商真我(Realme)可能将苹果挤下俄罗斯智能手机市场的前三名。根据MTS的数据,今年10月,苹果在俄罗斯智能手机的销量UWB定位如何解决化工厂人员定位的应用需求?化工厂作为高危工作环境,因此利用UWB实现化工厂人员定位以及仓库货物的定位监控,成为化工厂管控的迫切需求。通过对化工厂厂区内部和外部环境部署UWB定位系统,可以实现实时定位智能巡检信息化建设服务平台协办2021第十一届航空航天信息化建设合作峰会3月31日,由中国信息产业商会主办,中国信息产业商会人工智能分会信息化建设服务平台共同承办的2021第十一届航空航天信息化建设合作峰会在京隆重召开。峰会以新时代新征程新发展为主题,为什么这么多人反对联想,支持司马南?司马南对联想集团的几期视频内容在互联网上引起了轩然大波。这可能是自当年5g投票事件后,舆论对联想最大的一波讨伐声浪!从网络上反对者身份来看,更多的是普通人,也就是无产阶级(相对于1司马南又出手了,撕了联想,现在又来深挖滴滴,视频已经六期了撕联想的七期视频,它的主要内容也就是说到国有资产流失,高管高薪,经过网络的发酵,网民们的热情高涨,又添了一些料,给美军捐赠电脑,918日子,在台湾销售电脑用日本军国军旗,宣传海报,从李嘉诚到杰克马,再到今天的柳教父,为何会一个个跌落神坛?最近深陷舆论漩涡的柳教父和他的联想正遭受自创建以来最大的危机,目前来看联想从没有正面回应过种种质疑。不过不论结果如何,联想及柳教父已经从神坛跌落,而这一幕似乎极其眼熟。回想最近这十司马南继续猛怼联想司马南又出了新的一期联想系列的视频,这次讲了一个比较新颖的角度,是我以前也没想到的联想公司目前的业务里,有将近一半是通过金融赚来的,每年差不多20亿的利润。这个数据在香港上市公司的
全身舒爽!OSIM傲胜大天王3代按摩椅晒单前言自打家中人口兴旺之后,每天一家老小外加保姆都处在高负荷的家务之中,着实比上班还累。媳妇长时间抱孩子,肩颈肌肉经常酸痛难耐,自己捏两下无法起到显著的缓解作用,出去按摩又没有足够的轻薄本购买思路指南!荣耀MagicBook152021锐龙版外观解析前言AMD在去年的强势崛起令Intel似乎有些猝不及防,原本一边倒的局面甚至逆转为胜负参半,市场的激烈竞争使消费者成为最终赢家。一时间多样化配置的产品,也增加些许选购难度,到底什么会满地跑的监控头!TrifoLucyPet扫地机器人开箱测试前言不知从什么时候开始,原本扁平的扫地机器人额头多了个凸起LDS激光测距传感器,尽管在当时带来更为精确的地图绘制和路径规划特性,但降低了在复杂场景的通过能力,尤其很难进入低矮的沙发Studio认证设计本!机械革命UmiPlus火爆预售机械革命旗下Umi系列设计师本又增添了一员大将,17。3英寸大屏的UmiPlus已经登陆京东商城开启预售,仅需200元定金就能够以11499元价格入手经过了NVIDIAStudio满满年代感!40年前的松下高端卡座解析前言旷世神作EVA终于迎来完结,本人在看了不下10遍之后依然意犹未尽,感叹其几近完美的结局之外,也对剧情中的重要道具SonyWalkman磁带随身听,产生浓厚兴趣。想想自打接触数码20mm2。2kgRTX3070!机械革命UmiPlus设计师本评测前言说到大屏标压CPU高端独显,大家都会第一时间想到游戏本。随着全民自媒体时代来临,具备高性能特点的游戏本除了畅爽游戏外,被赋予了更多视频剪辑特效制作等创意工作。于是各大厂商看到这1。1kg的RTX3050游戏本?机械革命F1独显版评测前言目前笔记本市场呈现两极分化的局面,强调性能的游戏本由于功耗和发热的原因,基本都是傻大笨粗的形象。轻薄本又因为过于注重便携性,不得不舍为性能做出妥协。而机械革命作为有独立研发和工无延迟的畅爽体验!Cherry樱桃MX3。0SWireless无线机械键盘测试前言Cherry樱桃是机械键盘的开山鼻祖,凭借着手感出色和性能稳定的MX轴体,在市场上叱咤风云数十载。对于很多玩家而言,Cherry又代表着复古,毕竟早些年G80系列键盘留下的记忆苹果已成过去,iPhone13一点都不香2020年10月14日凌晨,苹果发布iPhone12系列4款5G手机,这是苹果首次推出5G手机。2020年10月13日下午,王守义十三香官方微博与粉丝互动回应12香不香不知道,王守将运动进行到底,长安UNI系列首款轿车谍照曝光近日,我们获悉了一组长安UNI系列首款轿车的谍照,新车延续了UNI家族式设计,未来新车主打运动风格,话不多说,一起来看看吧!外观方面采用了UNI引以为傲的无边界主题设计,细节方面还在MC我的世界服务器里一起和小伙伴玩超级玛丽魂斗罗坦克大战某天闲逛论坛,突然发现这样一篇帖子介绍了在MC服务器端使用插件来让玩家在游戏中玩FC红白机游戏的帖子娱乐BeautifulNes在服务器里和小伙伴一起玩FC游戏1。17。1服务端插