前面一篇文章讲了6种垃圾收集器分别是Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS(传送门) 今天我们来说一下G1(Garbage First)收集器,为什么把G1收集器单独拿出来说呢?它是垃圾收集器技术发展历史上的里程碑式的成果,下面我们细细道来
G1收集器开创了收集器面向局部手机的设计思路和基于Region的内存布局形式,G1也是遵循分代收集理论的,但是它的内存布局有以下几点变化
G1不再使用固定大小以及固定数量的分代区域划分,而是把连续的java堆划分为多个大小相等的独立区域(Region),每个Region区域可根据需要扮演新生代和老年代收集器还能对不同角色的Region进行不同的策略处理如果大小超过Region的一半就认为是大对象G1收集器的核心思想就是,去追踪各个Region的价值(这里的价值就是指回收这块Region区可以回收多大的内存空间),在后台维护一个优先级表,然后按照用户设置的收集停顿时间去按优先级表一次回收,保证了G1收集器在有限的时间内获取尽可能高的收集效率
G1的收集过程分为四个步骤:
初始标记 标记GC Roots能直接关联到的对象,并且修改TAMS指正的值,这个阶段需要停顿,但是时间很短 TAMS指针是什么呢?G1收集器为每个Region设计两个TAMS指针,把一部分的Region区域划分出来,用户并发垃圾收集过程中用户线程分配新对象并发标记 对堆中的内向进行可达性分析,递归的扫描整个对象图,并找出要回收的对象,这个阶段耗时很长,但是可以和用户线程并发执行最终标记 在并发标记阶段,难免会有用户线程打破了原来的对象图结构,解决这个问题问题的方案就是原始快照,最终标记就是对原始快照进行标记,这个阶段也是需要短暂的暂停筛选回收 对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间,选择性价比最高的Region区域进行回收。先讲Region存活的对象移动到新的Region区域中,然后对旧Region进行回收,这个阶段要进行对象的移动,所以必须要暂停用户线程。G1收集器真的是很经典的收集器,也是JDK9默认的收集器,他的运行机制要比之前说到的复杂的多,看到这里你学废了吗?