大家好,又见面了,我是你们的朋友全栈君。
翻译:http://www.oracle.com/technetwork/articles/java/g1gc-1984535.html
学习如何适配、调优G1 gc以用于评估、分析和性能优化。
G1 收集器 是用于hotspot JVM 的低停顿、适合服务器的分代垃圾收集器。G1 GC 使用并发和并行阶段来获得目标停顿时间和维持优秀的吞吐量。
当G1 GC 认为有必要进行垃圾回收时,首先回收存活数据最少的区域(garbage first)。
GC是一个内存管理工具。G1 GC通过以下操作来达成自动内存管理:
- 在年轻代分配对象,将老对象放到老年代。
- 通过并发(并行)标记阶段在老年代找到存活对象,java堆的占用率超过默认门槛值时hotspot JVM触发这个标记阶段。
- 通过并行复制以压缩存活对象来回收空闲内存。
在这里我们看看如何适配、调优G1 gc以用于评估、分析和性能优化–假设我们对于java垃圾回收有基本的了解。
G1 GC 是分区和分代的垃圾回收器,就是说Java堆被分成多个同等大小的区。JVM一起动就设置好区的大小。区的大小根据堆的大小不同在1M到32M之间。
区的数量不多于2048个。 eden, survivor和老年代是逻辑分代,不是连续的。
G1 GC 有一个试图达到的目标停顿时间(软实时)。回收年轻代时G1 GC调整年轻代大小来达到软实时目标。混合回收的时候,G1 GC 调整基于一个目标混合回收数量回收的老年代区的数量、堆里每个区的存活对象百分比、整体可接受的堆浪费比例。
G1 GC 通过从一个或者多个区里增量并行复制存活对象到不同的新的区里进行压缩来减少堆的碎片。目标是从有最多可回收空间的区开始,在试图不超出目标停顿时间的同时尽可能回收多的堆空间。
G1 GC使用独立的RSets来跟踪区里的引用,单独的RSets使并行和单独的区回收成为可能,因为只有这个区的RSets被扫描查找对这个区引用,而不是堆的所有RSets。
G1 GC使用post-write barrier来记录堆的变化和并且更新RSets。
垃圾回收阶段
除了构成stop-the-world (STW)年轻代和混合垃圾回收的疏散停顿,G1 GC也有并行、并发和多阶段标记循环。G1 GC使用在循环标记开始阶段对堆里的存活对象获取快照的Snapshot-At-The-Beginning (SATB)算法。存活对象集合由快照里的存活对象和从刚开始标记循环的时候分配的堆里的存活对象组成。G1 GC标记算法使用pre-write barrier来记录和标记那些属于逻辑快照一部分的对象。
年轻代垃圾回收
G1 GC满足大部分增加到eden区集合的区的内存分配请求,在年轻代GC阶段, G1GC回收eden区和前一次垃圾回收产生的survivor区。eden和survivor区的存活对象被复制或者疏散到新的区集合里。一个对象的目标区由对象的年龄决定:足够大年龄的对象被疏散到老年代区,否则到survivor区并且包含到下一次年轻代或者混合GC的CSet里。
混合垃圾回收
刚成功完成并发标记循环,G1 GC就从进行年轻代GC转换成混合GC。在混合GC阶段,G1GC 选择性地增加一些老区到要被回收的eden和survivor区里。老区的数量由下面讨论的一些标记控制。G1 GC 收集了足够的老区以后,G1返回开始进行年轻代GC直到下一次标记循环结束。
标记循环的各阶段
- 初级标记阶段:标记根。这个阶段是依托在一个正常的STW 年轻代GC上。
- 根区扫描阶段:G1 GC 扫描初级标记的survivor区查找对老年代的引用,并且标记被引用的对象。这个阶段和应用并发执行,并且必须在下一次 年轻代GC可以开始前完成。
- 并发标记阶段:G1 GC在整个堆里找到可达存活对象。这个阶段和应用并发执行,并且可以年轻代GC中断。
- 重新标记阶段:是 STW收集并且帮助完成标记循环。G1 GC放出SATB 缓存,跟踪没被访问的存活对象,进行引用处理。
- 清除阶段:进行STW的统计操作和RSets洗涤操作。在统计阶段,识别完全空的区和混合GC候补。清除阶段进行重置和返回空区给空闲列表时是部分并发。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/137619.html原文链接:https://javaforall.cn