栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

CMS与G1垃圾回收对比(取自——深入理解Java虚拟机)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CMS与G1垃圾回收对比(取自——深入理解Java虚拟机)

CMS 与 G1 的 GC 分析
  • CMS
    • GC算法
    • 跨代引用
    • 运作过程
    • 缺点有三
  • G1
    • GC算法
    • 跨代引用
      • Region是什么?
    • 运作过程
    • G1亮点
  • 内存分配(更加详细代码可参考书中内容)

CMS GC算法

标记清除算法:一定会带来磁盘碎片,最终Full GC,Stop The World。

跨代引用

假如要现在进行一次只局限于新生代区域内的收集(Minor GC),但新生代中的对象是完全有可 能被老年代所引用的,为了找出该区域中的存活对象,不得不在固定的GC Roots之外,再额外遍历整个老年代中 所有对象来确保可达性分析结果的正确性,反过来也是一样。

JVM 为了用尽量少的资源消耗解决跨代引用下的垃圾回收问题,引入了记忆集。

通过卡表(table card)来解决,只需一份,老年代到新生代的引用。

运作过程
  1. 初始标记 —— stop the world;
  2. 并发标记 ;
  3. 重新标记 —— stop the world;
  4. 并发清除 ;

其中,①和③的区别在于:
① 标记GC Roots能直接关联的对象,很快。
③ 修正并发标记期间,用户线程产生的标记变动,会比①时间长,但比②短。

缺点有三
  1. 对处理器资源非常敏感

虽然在并发阶段,没有stop the world,但会占用一部分线程,导致应用变慢,降低吞吐量。

  1. 浮动垃圾

由于在GC阶段,用户线程还需要持续运行,就需要预留足够的内存空间给用户线程使用,这就有可能发生,CMF(Concurrent Mode Failure)失败,进而发生stop the world的Full GC。

  1. 内存碎片合并整理

由于CMS的GC算法为标记清除,那么一定会出现由于磁盘碎片的问题,导致Full GC。
也就是说,Full GC 除了要清除不可达的垃圾对象,还不得不进行内存碎片的合并整理,这就一定会移动存活对象,使得停顿时间又会变长。

G1 GC算法

整体:标记 - 整理算法;
局部:标记 - 复制算法;

跨代引用

同样通过卡表(table crad)来解决。
但实现方式更为复杂,每个Region都需要维护一份卡表,因此内存占用更大。
这里的Region,不管新生代还是老年代都需要维护一份卡表。

Region是什么?

可以理解为这个Region是一个思想上的突破。

Region的产生:
把连续的Java堆划分为多个大小相等的独立空间,每一个Region根据需要,扮演新生代Eden空间,Survivor空间或者老年代空间。
G1认为只要大小超过了一个Region容量的一半的对象即可判定大对象,Region大小可通过 -XX:G1HeapRegionSize设定大小,值范围为1 ~ 32MB,应为2n。
大对象:超出一个Region的话,会被放入N个连续的HumongousRegion中,G1会把它当做老年代的一部分。

总结:虽然保留了新生代和老年代的概念,但新生代和老年代不再是固定的了,是一系列区域——region,且不需要连续的动态集合,Region作为单次回收的最小单元。

运作过程
  1. 初始标记 —— stop the world;
  2. 并发标记 ;
  3. 最终标记 —— stop the world;
  4. 筛选回收 —— stop the world;

其中,③和④均以并发进行,却不能与用户线程并发,所以stop the world。
④会冻结用户线程,有多条收集器线程并发复制对象。
所以才说,局部Region之间是标记 - 复制,整体来看是标记 - 整理算法。

G1亮点

-XX:MaxGCPauseMills
用户指定期望的GC停顿时间,默认200ms。

需注意:
不能设置的太短,假设设置的20ms,就会出现一个问题,
每次回收的对象很少,虽然短期内,看到应用运行很快,但是很快就会发现,应用运行时间一长就不行了。这是因为GC回收出来的内存跟不上用户产生的内存垃圾,最终一定会占满堆,引发Full GC,反而降低性能,所以一般值在100~300ms是比较合理的。

内存分配(更加详细代码可参考书中内容)
  1. 对象优先在Eden分配;
  2. 大对象直接进入老年代;

写程序应避免,短命大对象,会带来内存复制开销。

  1. 长期存活的对象,进入老年代;

-XX:MaxTenuringThreshold,默认15岁。

  1. 动态对象年龄判定;

如果在Survivor空间中,低于或等于某年龄的所有对象大小的总和,大于Survivor空间的一半,那么年龄大于或等于该年龄的对象就可以直接进入老年代,无需等到-XX:MaxTenuringThreshold中要求的年龄。

  1. 空间分配担保;

Minor GC还是Full GC ❓
①GC前,JVM会先检查老年代最大可用连续空间是否大于新生代所有对象的总空间,若成立 Minor GC,否则,进入②。
②检查老年代最大可用连续空间是否大于历次晋升老年代对象的平均大小,若成立,Minor GC(这属于冒险,可能会失败),否则,Full GC。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014820.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号