总结:G1收集器
1. 能够像CMS收集器一样跟应用线程并行操作
2.复制对象的同时对对象进行压缩和释放内存
3.灵活分配老年代,年轻代占比,不再固定
4. 收缩空闲空间不会造成由长GC引起的应用停顿时间。
5. 更精确的预测GC停顿时间
二、GC收集器比较
传统的垃圾收集器像Serial, Parallel, CMS 全部都将Java堆分成三个固定内存大小的部分,如年轻代,年老代和永久代,所有的内存中的Java对象都在三个部分中结束。
G1 收集器采用了不同的方法,它将整个Java堆分成2000个左右相同大小的堆区域,这些区域集像以前的收集器一样被分配到不同的角色,如Eden, Survivor和Old, 但是没有固定的区域数量被明确固定在某个角色上(所以不要配置年轻代大小),这将为内存使用上提供了更大的灵活性。
在执行垃圾收集时,G1操作十分类似于CMS收集器。G1执行一个并发全局标记阶段贯穿整个Java堆去判断对象的活跃度,标记阶段结束后,收集器知道哪一些区域是空的或者接近空的,它将先收集这些空的区域,通常会释放大量的内存空间,G1将其收集和压缩活动集中在可能充满可回收对象的堆区域上, 这也是收集器命名为G1的原因。G1使用了一个停顿预测模型根去满足用户自定义的停顿时间目标并且根据该目标选择一定数量的区域进行回收。
G1通过转移的方法将已被G1标识为区域当作可回收的垃圾进行回收,它把对象从1个或者多个区域中复制到单个区域,在复制的同时进行
压缩对象和释放内存,所有的转移过程通过多个处理器并行处理以降低暂停时间和增加吞吐量。因此,每一次垃圾回收,G1收集器持续地在用户预定的暂停时间内减少内存碎片。相对而言,CMS收集器不会做压缩,而PARALlelOld 收集器是对整个Java堆执行压缩,那么将导致较长停顿时间。
如果应用从CMS收集器或者ParallelOldGC到G1,你可能会发现相同数据规模情况下G1占用的内存比以前多了一些,多出的一些内存主要是用于存储账单数据结果,如Remembered Sets和Collection Sets.
- Remembered Sets, RSets跟踪每一个区域的对象引用,每一个区域都有一个Rsets, 它在区域启用一个独立且并行的集合,RSets大约增加5%左右的Overhead。
- Collection Sets, CSets是放置可被收集器回收的区域集合,所有在这个集合的数据对象在垃圾回收期间均可被转移,这些区域可能是Eden,Survivor 或者老年代。CSets大约有增加1%左右的overhead.
和CMS对比:
G1
CMS
设计原则
首先收集尽可能多的垃圾(Garbage First)
尽可能少而块地执行GC,以停顿时间为目标
垃圾回收时机
启发式算法,在老年代找出具有高收集收益的分区进行收集
内存耗尽(新生代)或者快耗尽(老年代)
内存划分
将内存划分为一个个相等大小的内存分区(Region),每个区域都可能有四种状态:E(eden)、S(Survial)、O(old)、空闲
分为新生代和老年代2块连续的内存空间
是否产生垃圾碎片
将一组或多组区域(称为回收集 (CSet))中的存活对象以增量、并行的方式复制到不同的新区域来实现压缩,从而减少堆碎片
采用标记删除,会产生碎片
三、G1 回收步骤
四、G1 调优注意事项
1. 年轻代大小
避免使用?-Xmn?选项或?-XX:NewRatio?等其他相关选项显式设置年轻代大小,因为固定年轻代的大小会覆盖暂停时间目标。
动态调节年轻代和总堆的比例。
G1可以根据用户设置的暂停时间目标自动调整年轻代和总堆大小,暂停目标越短年轻代空间越小、总空间就越大;
整个年轻代内存会在初始空间-XX:G1NewSizePercent(默认整堆5%)与最大空间-XX:G1MaxNewSizePercent(默认60%)之间动态变化,
且由参数目标暂停时间-XX:MaxGCPauseMillis(默认200ms)、需要扩缩容的大小以及分区的已记忆集合(RSet)计算得到。
当然,G1依然可以设置固定的年轻代大小(参数-XX:NewRatio、-Xmn),但同时暂停目标将失去意义。
2. 暂停时间目标
每当对垃圾回收进行评估或调优时,都会涉及到延迟与吞吐量的权衡。G1是增量垃圾回收器, 其吞吐量目标是 90% 的应用程序时间和 10%的垃圾回收时间。因此,暂停时间目标不要太严苛。目标太过严苛表示您愿意承受更多的垃圾回收开销,而这会直接影响到吞吐量。
G1有一个及其重要的特性:软实时(soft real-time)。所谓的实时垃圾回收,是指在要求的时间内完成垃圾回收。“软实时”则是指,用户可以指定垃圾回收时间的限时,G1会努力在这个时限内完成垃圾回收,但是G1并不担保每次都能在这个时限内完成垃圾回收。通过设定一个合理的目标,可以让达到90%以上的垃圾回收时间都在这个时限内。
五、G1 主要参数配置
六、垃圾回收过程
1、YGC
在Eden充满时触发,在回收之后所有之前属于Eden的区块全变成空白。然后把剩余的存活对象移动到S区。
很多情况下,S区的对象会有部分晋升到Old区,另外如果S区已满、Eden存活的对象会直接晋升到Old区,这种情况下Old的空间就会涨
这个过程会对年轻代的对象有一个短暂的停顿
2、并发标记阶段
G1并发标记周期可以分成几个阶段、其中有些需要暂停应用线程。有些是后台并行处理,不需要暂停应用
- 初始标记。需要暂停应用线程这个阶段会暂停所有应用线程。部分原因是这个过程会执行一次YGC
- 并发扫描。后台线程并行处理,不会暂停应用
- 并发标记。在root扫描完成后,G1进入了一个并发标记阶段。这个阶段也是完全后台进行的
- 并发标记阶段是可以被打断的,比如这个过程中发生了YGC就会。这个阶段之后会有一个二次标记阶段和清理阶段。这两个阶段同样会暂停应用线程,但时间很短。接下来还有额外的一次并发清理阶段
3、混合GC
接下来G1执行一系列的混合GC。这个时期因为会同时进行YGC和清理上面已标记为X的区域,所以称之为混合阶段。
每次混合GC只是清理一部分的O区内存,整个GC会一直持续到几乎所有的标记区域垃圾对象都被回收,这个阶段完了之后G1会重新回到正常的YGC阶段。周期性的,当O区内存占用达到一定数量之后G1又会开启一次新的并行GC阶段.
4、FullGC
如果对象内存分配速度过快,mixed gc来不及回收,导致老年代被填满,就会触发 一次full gc,G1的full gc算法就是单线程执行的serial old gc,会导致异常长时间的暂停时间,需要进行不断的调优,尽可能的避免full gc.
参考:
G1垃圾收集器入门
以上是 总结:G1收集器 的全部内容, 来源链接: utcz.com/z/515940.html