乐趣区

关于后端:深入浅出JVM十八之并发垃圾收集器G1

在这篇文章 深入浅出 JVM(十六)之三色标记法与并发可达性剖析 中,咱们曾阐明过 GC 线程和用户线程并发执行导致的对象隐没问题,能够应用增量更新或原始快照的形式来解决

上文深入浅出 JVM(十七)之并发垃圾收集器 CMS 中形容过应用增量更新的 CMS,本文将介绍应用原始快照的 G1 垃圾收集器

Garbage First

G1 全称 Garbage First 面向服务端的垃圾收集器,G1 诞生是为了 在提早可控的状况下尽可能高的吞吐量

Region

G1 不再应用分代收集算法,把 Java 堆内存分为多个大小相等的区域(Region),面向堆内存任何局部来组成区 (Region) 进行收集,哪块内存垃圾最多,收益最大就回收哪块

Region 分为新生代 Eden、新生代 Survive、大对象 Humongous

大多数状况下 Humongous 被当成老年代

当大对象太大,一个 Humongous 不够时,应用间断多个 Humongous 存储

每个区域设计 2 个 TAMS(Top at Mark Start) 指针,把区域中一部分空间划分进去用来为新对象分配内存(指针碰撞,内存规整)

G1 从整体上能够看成应用 标记 - 整顿算法 ,从部分上能够看成应用 区域间复制算法

执行过程与流程图

G1 采纳 原始快照 来解决 GC 线程与用户线程并发时的对象隐没问题

G1 收集器在后盾保护一个 优先级队列跟踪各个区域中的垃圾回收价值(回收垃圾的大小和回收工夫的状况)

依据 -XX:MaxGCPauseMillis 用户规定的 收集进展工夫来优先回收垃圾回收价值最大的区域

执行过程

  1. 初始标记 : 标记 GC Roots 能间接关联的对象,批改 TAMS 指针(进展用户线程,耗时短)
  2. 并发标记 : 从 GC Roots 间接关联对象开始遍历整个援用链的过程(GC 线程与用户线程并发执行耗时长),扫描完还要解决原始快照记录在并发时有援用变动的对象
  3. 最终标记 : 解决并发阶段遗留下来的大量原始快照记录(进展用户线程,耗时短)
  4. 筛选回收 : 更新区域的垃圾回收价值,把各个区域的垃圾回收价值(要算老本: 回收工夫)在优先级队列中排序,依据用户所冀望的进展工夫制订回收打算,把要回收的那片区域存活的对象复制到空区域中(复制对象要暂停用户线程,GC 线程并行执行)

如果冀望进展工夫设置太短(不符合实际),因为进展工夫短,回收垃圾速度 < 为新对象分配内存速度,会导致堆满 Full GC 反而会升高性能

参数

-XX:+UseG1GC 应用 G1 收集器

-XX:G1HeapRegionSize设置每个 region 大小

-XX:MaxGCPauseMillis设置预期进展工夫(默认 200ms,最好不要太小)

-XX:ParallelGCThread设置 GC 线程数

-XX:ConcGCThreads设置并发标记线程数

-XX:InitiatingHeapOccupancyPercent设置触发老年代 GC 的堆占用率阈值

特点

长处

  1. 整体: 标记 - 整顿、部分: 复制,不会产生内存碎片
  2. 从用户冀望工夫来回收垃圾价值最高的垃圾
  3. 原始快照的益处(记录旧援用,不须要增加新援用记录,缩小并发标记、从新标记阶段的耗费)

毛病

  1. 因为有很多区域,跨区域援用对象问题频繁呈现,每个区域要保护记忆集(Key: 别的区域地址 Value: 汇合存储卡表的索引号),卡表实现简单(其余卡表: 我指向谁,这里的卡表: 我指向谁 + 谁指向我),所以 占用内存更大
  2. 执行负载大(写屏障操作简单)

    写后屏障保护简单的卡表

    原始快照的害处(须要记录旧援用): 写前屏障跟踪并发指针变动,在用户程序运行中产生有跟踪援用变动带来的额外负担

    CMS 写屏障能够间接同步,而 G1 写屏障太简单要把写前屏障和写后屏障中做的事放到队列中,异步解决

总结

本篇文章深入浅出的介绍 G1 并发垃圾收集器 Region、执行过程、流程图、参数、特点等常识

G1 不应用分代算法,将内存分为 Region,Region 分为 Eden、Survive、Humongous,从部分能够看成复制算法,整顿上看成标记 - 整顿算法

G1 初始标记枚举 GC 根节点,在并发标记中应用原始快照解决对象隐没问题,最终标记后应用优先级队列优先回收价值高的 region

G1 不会产生内存碎片,可能在冀望的低提早中实现价值最大的清理,但保护跨代援用、写后屏障等开销大

内存较大、处理器较多、冀望低提早、面向服务端的垃圾收集器能够抉择 G1

最初(一键三连求求拉~)

本篇文章将被支出 JVM 专栏,感觉不错感兴趣的同学能够珍藏专栏哟~

本篇文章笔记以及案例被支出 gitee-StudyJava、github-StudyJava 感兴趣的同学能够 stat 下继续关注喔 \~

有什么问题能够在评论区交换,如果感觉菜菜写的不错,能够点赞、关注、珍藏反对一下 \~

关注菜菜,分享更多干货,公众号:菜菜的后端私房菜

本文由博客一文多发平台 OpenWrite 公布!

退出移动版