关于CMS收集器的一点疑问。

当并发标记完之后要进行重新标记。那么并发标记的意义是什么?直接重新标记不就完了?
还有标记清除算法。如果清除后剩余的存活对象之间连续的内存不够分配给下一个对象,会OOM吗?
CMS为什么要有一个初始标记的过程呢,而不是直接并发标记?
求解惑,谢谢。

全部评论
首先CMS是一个old gen收集器。 initial mark阶段需要找到所有的GC roots,这个阶段会STW,GC roots选取比较快,所以停顿时间不会太长。 concurrent mark阶段,GC roots tracing,扫描整个heap上(包括young gen和old gen)的所有存活的对象,这个阶段是和用户线程并发执行的,用户线程感知不到停顿。 remark阶段,需要修正在concurrent mark阶段发生变化的引用关系,具体就是young gen有新的对象加入,需要扫描整个young gen,修正引用关系,这个阶段需要STW,CMS最长的停顿时间在这个阶段,young gen越大,停顿时间越长(CMS之前可先跑一次young GC,降低remark阶段停顿时间)。 concurrent sweep阶段:并发清除。 CMS用的是mark sweep算法,会有内存碎片,如果CMS GC之后old gen仍然无法分配,就会启动backup的serial old进行full GC。平时CMS GC old gen跑到一定的容量的时候,也会用serial old跑一次full GC。
点赞 回复 分享
发布于 2017-09-03 21:55
对于初始标记、并发标记、重新标记,我的理解是,初始标记只是JVM标记GC Roots能够直接关联的对象(直接关联应该是直接引用的对象),所以“Stop the world”;并发标记时进行 GC Root Tracing,也就是查看哪些对象是可达的,所以GC线程和用户线程并行运行;重新标记是用来标记在并发标记过程中由于程序运行产生的变动对象,也需要“Stop the world”。
点赞 回复 分享
发布于 2017-09-03 21:16
并发标记期间,用户程序也在运行吖,它有可能会对已经标记过的某些对象的标记记录产生影响,所以要重新标记。 标记清除后,内存不够分配下一个对象的话,会再次触发新的垃圾收集动作吧,再不够的话就OOM。哈哈,个人理解,不知道对不对。
点赞 回复 分享
发布于 2017-09-03 20:53
首先每一种算法都是有其需求的。之所以出现CMS算法,是希望尽可能减少GC过程对正常程序的影响。而这个影响来源于STW(stop the world),因为要清除无用的对象必须要在正常程序对这些对象无操作的情况下进行,否则可能出差错。 所以CMS算法把这个查询过程分了3步,其中第二步(tracing)是最费时间的,为了减少STW,第二步采用并发的模式进行,即不影响正常程序,这也就是为什么CMS算法采用分时标记的原因
点赞 回复 分享
发布于 2017-09-03 21:55
初始标记:把根搜索算法里的根对象标记出来,这个过程是stop the world的。 并发标记:并发的标记从根对象出发能引用到的所有对象,这个过程是不阻塞用户线程的。 再次标记:在并发标记过程中,可能对象的引用状态发生了变化,再检查一遍,这个过程stop the world。 垃圾回收:回收标记为垃圾的对象。 上面是自己的理解,下边是粘的: 根对象: 虚拟机栈(栈帧中的本地变量表)中的引用对象 本地方法栈中引用的对象 方法区中类静态属性引用的对象 方法区中常量引用的对象
点赞 回复 分享
发布于 2017-09-03 21:20
对于第二个问题我的想法是,并发清除后的内存是不规整的,所以在为需要连续存储空间的大对象(数组或很大的字符串)分配空间时,会因为找不到连续的空间而触发一次GC。对于不需要连续存储空间的对象来说,JVM可以使用“空闲列表”来分配内存,所以不会触发GC。
点赞 回复 分享
发布于 2017-09-03 21:01
借楼问一下CMS为什么要有一个初始标记的过程呢,而不是直接并发标记?
点赞 回复 分享
发布于 2017-09-03 20:58

相关推荐

专业嗎喽:个人信息名字太大,合到电话邮箱那一栏就行,有党员写过党,剩下其他全删,站空太大了 把实习经历丰富,放最前面,然后是个人评价,技能之类的,然后是学校信息。项目经历最后面,可以就选一个自己擅长的。 现在是学校不是92就扣分的,没必要放前面。 然后现在看重实习经历>竞赛经历(校园经历)>课程项目经历
点赞 评论 收藏
分享
12-04 16:18
已编辑
东华理工大学 前端工程师
面试官全程关摄像头1.自我介绍一下2.React和Vue哪个更熟悉一点3.你在之前那段实习经历中有没有什么技术性的突破(我只是实习了44天工作28天,我把我能说的都说了)4.你封装的哪个表单组件支不支持动态传值5.自己在实习阶段Vue3项目封装过hook吗6.hook有什么作用7.Vue2和Vue3的响应式区别(我说一个是proxy是拦截所有的底层操作,Object.defineProperty本身就是一个底层操作,有些东西拦截不了,比如数组的一些操作还有等等,面试官就说实在要拦截能不能拦截????我心想肯定不行呀,他的底层机制就不允许吧)8.pinia和vuex的区别(这个回答不出来是我太久没用了)9.pinia和zustand的区别,怎么选(直接给我干懵了)(我说react能用pinia吗  他说要用的话也可以)10.渲染一万条数据,怎么解决页面卡顿问题(我说分页、监听滚轮动态加载,纯数据展示好像还可以用canvas画)(估计是没说虚拟表单,感觉不满意)11.type和interface的区别12.ts的泛型有哪些作用(我就说了一个结构相同但是类型不同的时候可以用,比如请求响应的接口,每次的data不同,这里能用一个泛型,他问我还有什么)13.你项目用的是React,如果让你再写一遍你会选择什么14.pnpm、npm、yarn的区别15.dependencies和devdependencies的区别总而言之太久没面试了,上一段实习的面试js问了很多。结果这次js一点没问,网络方面也没考,表现得很一般,但是知道自己的问题了  好好准备,等待明天的影石360和周四的腾讯了  加油!!!
解zj:大三的第一段面试居然是这样的结局
查看15道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务