G1(Garbage First Collector)是十分重要的垃圾收集器。
G1的内存布局

- 2048个region
- 新生代初始占比5%
- 新生代占比超过60%就会进行新生代垃圾回收
- 如果一个对象的大小超过一个region的50%以上,就会放在
Humongous
区
Full Young GC
最开始的时候堆中只有年轻代。
默认在新生代占比达60%的时候触发。
- Root Scanning
- Update RS
- Process RS Detect the Eden objects pointed by Old objects
- Object Copy
- Reference Processing process Soft,Weak,Phantom,Final,JNI Weak references
Mixed GC
Mixed GC大致可划分为全局并发标记(global concurrent marking)和拷贝存活对象(evacuation)两个大部分
当老年代达到45%时触发。
global concurrent marking
- 初始标记(initial marking):暂停阶段。扫描根集合,标记所有从根集合可直接到达的对象并将它们的字段压入扫描栈(marking stack)中等到后续扫描。
- 并发标记(concurrent marking):并发阶段。不断从扫描栈取出引用递归扫描整个堆里的对象图。每扫描到一个对象就会对其标记,并将其字段压入扫描栈。重复扫描过程直到扫描栈清空。过程中还会扫描SATB write barrier所记录下的引用。
- 最终标记(final marking,在实现中也叫remarking):暂停阶段。在完成并发标记后,每个Java线程还会有一些剩下的SATB write barrier记录的引用尚未处理。这个阶段就负责把剩下的引用处理完。同时这个阶段也进行弱引用处理(reference processing)。 注意这个暂停与CMS的remark有一个本质上的区别,那就是这个暂停只需要扫描SATB buffer,而CMS的remark需要重新扫描mod-union table里的dirty card外加整个根集合,而此时整个young gen(不管对象死活)都会被当作根集合的一部分,因而CMS remark有可能会非常慢。
- 清理(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...