G1垃圾收集器
🌀

G1垃圾收集器

Created
May 26, 2021 01:46 PM
status
being serialized
G1(Garbage First Collector)是十分重要的垃圾收集器。

G1的内存布局

notion image
  • 2048个region
  • 新生代初始占比5%
  • 新生代占比超过60%就会进行新生代垃圾回收
  • 如果一个对象的大小超过一个region的50%以上,就会放在Humongous

Full Young GC

最开始的时候堆中只有年轻代。
默认在新生代占比达60%的时候触发。
  1. Root Scanning
  1. Update RS
  1. Process RS Detect the Eden objects pointed by Old objects
  1. Object Copy
  1. Reference Processing process Soft,Weak,Phantom,Final,JNI Weak references

Mixed GC

Mixed GC大致可划分为全局并发标记(global concurrent marking)和拷贝存活对象(evacuation)两个大部分 当老年代达到45%时触发。

global concurrent marking

  1. 初始标记(initial marking):暂停阶段。扫描根集合,标记所有从根集合可直接到达的对象并将它们的字段压入扫描栈(marking stack)中等到后续扫描。
  1. 并发标记(concurrent marking):并发阶段。不断从扫描栈取出引用递归扫描整个堆里的对象图。每扫描到一个对象就会对其标记,并将其字段压入扫描栈。重复扫描过程直到扫描栈清空。过程中还会扫描SATB write barrier所记录下的引用。
  1. 最终标记(final marking,在实现中也叫remarking):暂停阶段。在完成并发标记后,每个Java线程还会有一些剩下的SATB write barrier记录的引用尚未处理。这个阶段就负责把剩下的引用处理完。同时这个阶段也进行弱引用处理(reference processing)。 注意这个暂停与CMS的remark有一个本质上的区别,那就是这个暂停只需要扫描SATB buffer,而CMS的remark需要重新扫描mod-union table里的dirty card外加整个根集合,而此时整个young gen(不管对象死活)都会被当作根集合的一部分,因而CMS remark有可能会非常慢。
  1. 清理(cleanup):暂停阶段。清点和重置标记状态。这个阶段有点像mark-sweep中的sweep阶段,不过不是在堆上sweep实际对象,而是在marking bitmap里统计每个region被标记为活的对象有多少。这个阶段如果发现完全没有活对象的region就会将其整体回收到可分配region列表中。

Evacuation

Evacuation阶段是全暂停的。它负责把一部分region里的活对象拷贝到空region里去,然后回收原本的region的空间。

可预测的停顿

这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。

实现方式

G1 收集器在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的 Region(这也就是它的名字 Garbage-First 的由来) 。

Loading Comments...