可靠的采集神器(4.垃圾收集过程G1收集器的运行*敏*感*词*如下的Mixed和继承人 )

优采云 发布时间: 2021-09-05 19:29

  可靠的采集神器(4.垃圾收集过程G1收集器的运行*敏*感*词*如下的Mixed和继承人

)

  1.简介

  Garbage First(简称G1)collector)是垃圾采集技术发展史上的里程碑式成就:开创了“面向本地采集”的设计思想和“基于区域”的内存布局形式.

  G1采集器是一个主要针对服务器应用的垃圾采集器,它的定位是“cms采集器的替代者和继承者”。其发展简史如下:

  2.堆内存划分

  虽然 G1 采集器也遵循分代采集理论,但它的堆内存布局与其他采集器有很大不同:

  G1采集器的堆内存划分如图:

  

  3. 暂停时间模型3.1 暂停时间模型

  Pause Prediction Model:指定在M毫秒的时间段内,垃圾回收花费的时间很可能不超过N毫秒。

  G1采集器之所以能建立可预测的暂停时间模型,是因为它把Region作为单次恢复的最小单位(每次采集的内存空间是Region大小的整数倍),这样可以有计划地避免整个Java堆的垃圾回收。

  更具体的处理思路:让G1采集器跟踪每个Region中垃圾堆积的“值”,然后在后台维护一个优先级列表,根据用户每次设置的采集暂停时间优先回收时间收益最大的区域(这就是“垃圾优先”名称的由来)。

  衡量“价值”的标准是:每次采集所获得的空间量和采集所需时间的经验值。

  3.2 混合 GC

  对于G1采集器之前的所有其他采集器(包括cms采集器),垃圾采集的目标范围要么是整个年轻代(Minor GC),要么是整个老年代(Major GC),要么是整个Java 堆(Full GC)。

  而G1跳出了这个笼子:它可以面对堆内存的任何部分,形成一个回采集(通常称为CSet)进行回收。衡量的标准不再是它属于哪一代,而是哪一块内存收录的垃圾量最大,回收收益最大。这是G1采集器的Mixed GC模式。

  4.垃圾采集过程

  G1采集器运行*敏*感*词*如下:

  

  其操作过程大致可以分为以下四个步骤:

  4.1 初始标记

  特点

  TAMS:Top at Mark Start,Region中的指针,用于并发标记时为对象分配内存空间。

  4.2 并发标记

  堆中对象的可达性分析从GC Root开始,递归扫描整个堆中的对象图,找到需要回收的对象。

  另外,在扫描完成后,需要对STAB记录的并发期间引用发生变化的对象进行重新处理。

  STAB: Snapshot At The Beginning,原创快照,参考前文的6.3 部分。

  4.3 最终成绩

  特点

  4.4 筛选回收

  特点

  5. 一些细节5.1 跨区域引用对象

  解决办法是使用前面《》第4节中的“内存集”,避免将整个堆扫描为GC Roots。

  然而,G1 的内存集更复杂,因为:

  根据经验,G1至少需要Java堆大小的10%~20%左右的额外内存空间来维持采集器的工作。

  5.2 并发标记

  解决方案在上一篇第6节分析:cms采集器采用增量更新算法,而G1采集器采用原创快照(STAB)算法实现。

  另外,由于用户线程在并发标记时还在执行,所以肯定会继续创建新对象。

  G1为每个Region设计了两个名为TAMS(Top at Mark Start)的指针,将Region中的一部分空间划分为并发采集过程中的新对象分配(默认都是alive的,没有收录在范围内)回收)。

  需要注意的是,如果内存回收速度跟不上内存分配速度,G1采集器也会强制冻结用户线程的执行,导致Full GC和长时间“Stop The World” .

  5.3 可靠的暂停模型

  G1采集器的暂停模型基于Decaying Average的理论基础:垃圾采集过程中,G1采集器会根据每个Region的采集时间,内存中脏卡的数量等. 分析平均值、标准差等

  “衰减平均值”比普通平均值更准确地表示“最近”的平均值状态。此信息用于预测如果回收现在开始将采集哪些区域,以便可以限制采集不超过预期的暂停时间。获得最高利润。

  6. G1 VS cms

  G1 采集器经常与cms 采集器进行比较。

  不管G1的一些创新设计:可以指定最大暂停时间,子区域的内存布局,根据收入动态确定集合等等,这里只说其他一些比较常见的地点。

  6.1 采集算法

  G1的两种算法在运行过程中防止内存空间碎片化,并在垃圾回收完成后提供正常可用的内存。而且这对于程序长时间运行是有好处的(大对象分配内存时,由于无法找到连续的内存空间,不容易提前触发下一次采集)。

  6.2 内存占用

  cms 和 G1 都使用卡片表来处理跨代指针,但是 G1 的卡片表实现更复杂,区域更多(本文5.1 部分)。

  相比之下cms的卡片列表比较简单,只有一份,而且只需要处理老一代到新生代的引用。

  与cms相比,G1的内存占用更大。

  6.3 额外的执行负载

  由于两者的实现细节不同,用户程序执行时的负载会有所不同。以写屏障为例:

  G1 的写屏障比cms 消耗更多的计算资源。所以cms写屏障是同步操作,而G1使用的是类似消息队列的异步操作。

  总体:

  这个临界点大概在6~8G(经验值)之间。

  一些相关的虚拟机参数如下:

  <p># 使用 G1 收集器

  -XX:+UseG1GC

  

  # 设置 Region 大小(范围 1~32M,且为 2 的 N 次幂)

  -XX:G1HeapRegionSize

  

  # 最大收集停顿时间(默认 200 毫秒)

  -XX:MaxGCPauseMillis</p>

  本文主要内容总结如下:

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线