深入理解Java虚拟机——G1垃圾收集(二)

92 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

G1的垃圾收集可以分为四个部分

  1. 初始标记:(单线程,STW)标记出GC Roots,并修改TAMS指针的值,为了用户线程运行时有可用的Region来分配新对象。这个阶段需要停顿但耗时很短。并且在Minor GC的时候同步完成,实际没有额外的停顿。
  2. 并发标记:(多线程)根据GC Root开始对堆中的对象进行可达性分析,与用户线程并行。
  3. 最终标记:(多线程,STW)暂停用户线程,处理并发阶段结束后遗留下的STAB记录。
  4. 筛选回收:(多线程,STW)统计Region的数据,根据回收价值和成本排序,根据用户期望的停顿时间来指定回收计划。实际回收时会将存活的对象复制到空Region中,清理掉旧Region的全部空间。由于需要移动存活对象,必须暂停用户线程。

image.png

G1根据用户期望的停顿时间来制定垃圾收集计划,默认停顿时间是200ms,如果指定的期望停顿时间过低,垃圾收集速度跟不上分配速度,导致垃圾慢慢堆积,最终占满堆引发Full GC而降低性能,通常把期望停顿时间设置为一两百毫秒三四百毫秒比较合理。

从G1垃圾收集器开始,垃圾收集器不在追求把整个Java堆全部清理干净,而是追求能够应付应用的内存分配速率,G1是收集器技术发展的一个。