首页
学习
活动
专区
工具
TVP
发布

EffectiveCoding

专栏成员
113
文章
103445
阅读量
28
订阅数
JVM 《三 JVM 中的垃圾回收器 — — 其他》
除去上一篇说的CMS,剩下的都是这几类了,然后根据Old or New 自行分配就好了
邹志全
2020-02-25
3400
JVM 《二 JVM 中的垃圾回收器 — — CMS&G1》
这是最常见的两个垃圾回收器,也是现阶段JVM中使用的最多的。 先说CMS,Concurrent Mark Sweep,,名字全称是Concurrent Low Pause Collector。看缩写及名字就知道啦,并发进行的、基于标记-清除的,低停顿的老年代回收器。 CMS最大的目标是至于最短的GC停顿时间,我都知道GC过程中会有一段Stop the world的过程。CMS的目标是如何最大的减少这部分停顿。 其中CMS 的GC过程是这样的: 1>初始化标记阶段 标记下与Root 节点直接相连的节点,当然了这个过程是需要暂停其他的线程的。但是由于仅仅只是标记直接相连的节点,停顿时间是非常短的。 2>并发标记阶段 首先,这个过程是用户线程与GC同时进行的,然后用一种类似于闭包的方式去发现并且标记可达的对象。这里需要注意一点儿,这个过程结束后是不能保证可达对象是被全部标记的。因为在过程中,用户线程可能正在不断的达到新的对象,GC线程是无法保证实时性的。 3>确定标记阶段 前几个阶段标记了所有与GC Root节点相链的节点、然后标记了几乎所有的可达对象。将上一阶段做了指针更新的区域和root合并为一个伪root集合,并对其做tracing。从而可以保证真正可达的对象一定被标记了。但会产生一部分被标记为可达,但其实已经是不可达的了,由于已经没有了到达这个区域的路径,所以并没有办法将它的标志位置为0,则造成了一个暂时的内存泄漏,哈仅仅是暂时的,这部分空间会在下一次收集阶段被清扫掉的。 4>并发清理阶段 当我们已经确定好要清理哪些对象后,我们的清理工作就可以开展了,与用户线程一块儿进行。 看完回收过程,CMS的优缺点已经非常清晰了 先说缺点 CMS 对CPU资源是非常敏感的,这点毋庸置疑。然后CMS GC的过程中会出现一些浮动垃圾,不巧的是CMS对这些浮动垃圾是无能为力的(这里的浮动垃圾是指在清理阶段是会出现新的垃圾,但是这部分垃圾未被标示因故无法被清理)。然后最后一点是CMS算法的缺陷,即因标记清理,产生空间碎片,对于这一点CMS提供了整理空间碎片的机制,但是对应的是因为需要抽出时间来整理空间所以导致停顿时间增加,这一点对于CMS来说很遗憾无法两全。 然后是优点 CMS最大的特点也是它最大的优点,并发收集、低停顿。 说完CMS,下一个G1 现存比较先进的收集器。是要准备替代CMS的一款收集器。 先说明一点,在G1中分代是被弱化的,没有物理上的分区,仅仅是概念或者说逻辑上的分区而已,这算是GC的一种趋势吧。 G1的全称叫做Garbage First,简单来说也就是第一时间回收垃圾。这么叫当然是有道理的,G1 是把内存看作一个又一个的块儿,每一块儿可能是O区,也可能是Y区(O、Y并非连续)。当并发收集发生时、在清理区块时虽然停顿仍然是必要的,但是G1会优先去收集那些垃圾多的块儿(这也就是所谓的优先处理垃圾) G1通常含有四种操作方式,YGC、并发阶段、混合模式,还有发生问题时出现的Full GC 1>YGC也就是指的 young GC,在Eden满时触发,将存活的对象分别对应的移到Survivor区&old区 2>并发阶段,在至少一次YGC之后,Eden已经被清空,然后又有新的垃圾出现在Eden中,O区现在是增大了的因为回收过程中会有新的对象进入O区,然后G1会标示出O区中垃圾最多的区域(也就是回收收益最高的区域)。这个阶段的目的,我感觉是为了标记处垃圾最多的块儿,为了更好的收集垃圾。 并发阶段大约分为这么几个过程: 初始标记阶段(会发生一次YGC,会暂停所有的应用线程 (可以理解为在同一段暂停时间做了两件事儿))开始扫描根区域(YGC必须是在这次扫描完进行的这就不用多说了) 这个阶段之后会出现二次标记阶段和清理阶段(这两个过程也会去停用户线程但是时间非常短) 之后再进行一次额外的并发清理阶段 这个过程回收的区域比较少,主要是为了发现哪一块可回收的垃圾最多。在这个阶段垃圾的数量及哪一块垃圾多少已经很清楚了 3>混合GC,也就是对于垃圾特别多的重点区域进行回收,然后是正常的Eden清理,Survivor区的整理。可以理解成一种内存整理及压缩的过程吧。 通过这些阶段及回收方式很轻易就能发现,相对于CMS来说,G1有这么几个显著的特点 1>压缩内存 2>更少的空间碎片 3>分区弱化,内存的使用更加灵活了 4>G1 相对于其他的回收器,可以作用于各个区域,更不是仅限于某个 5>G1 是可以设置预期停顿时间的,这恐怕是最大的进步了(有种实时收集的感觉,也算是个好的先兆吧) 另外,G1可以说是并行&并发的,这样对CPU的利用率更高 注: G1收集器在Java 7中就已经出现了 CMS是在1.5时出现的
邹志全
2020-02-25
4020
没有更多了
社区活动
【纪录片】中国数据库前世今生
穿越半个世纪,探寻中国数据库50年的发展历程
Python精品学习库
代码在线跑,知识轻松学
博客搬家 | 分享价值百万资源包
自行/邀约他人一键搬运博客,速成社区影响力并领取好礼
技术创作特训营·精选知识专栏
往期视频·千货材料·成员作品 最新动态
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档