赞
踩
目录
2.2、分区Region的Collect Set(CSet)
为了取代 CMS 收集器,CMS有以下缺点:
G1优点:
G1是标记-清除还是标记-整理算法:
G1 收集器不采用传统的新生代和老年代物理隔离方式收集,采用的是逻辑上划分新生代和老年代。将整个堆内存划分为2048个大小相等的独立内存块Region,大小是2的N次方大概每一块在 1M - 32M 之间,使用不同的Region来表示新生代和老年代,再要求相同类型的 Region 在物理内存上相邻所以是逻辑上划分。每个 Region 分区只能是一种角色,Eden区、S区、老年代O区、H巨型对象区。
什么是H巨型对象区:大小超过一个Region容量的50%以上的对象存放的区域,为了解决如果它是一个短期存活的巨型对象,放入老年代就会对垃圾收集器造成负面影响,触发老年代频繁GC,所以引入H区概念。如果一个H区装不下巨型对象,G1会寻找连续的H分区来存储,如果寻找不到连续的H区,就启动 Full GC 全局回收。
RSet是一个反向指针( HashTable 的集合),记录了其它 Region 对当前 Region 的引用情况。回收某个Region时,不需要执行全堆扫描(串行和并行收集器就需要),只需扫描它的 RSet 就可以找到外部引用,来确定引用本Region分区内的对象是否存活。本Region的引用不用记录、新生代的引用也不用记录(因为GC会全部扫描新生代),所以只需要记录新生代和老年代之间的引用。
哈希表(HashTable )是实现 RSet 的一种常见方式。一个Region可能有多个线程在并发修改,因此也可能会并发修改 RSet。为避免冲突,G1垃圾回收器进一步把 RSet 划分成了多个 HashTable,每个线程都在各自的 HashTable 里修改,从逻辑上来说,RSet 就是这些 HashTable 的集合。
RSet 的写屏障:每次将一个老年代对象的引用修改为指向年轻代对象,都会被写屏障捕获并记录下来,因此在年轻代回收的时候,就可以避免扫描整个老年代来查找根
一个 Card Table 将一个 Region 在逻辑上划分为若干个固定大小(介于128到512字节之间)的连续区域,每个区域称之为卡片 Card,因此 Card 是堆内存中的最小可用粒度,分配的对象会占用物理上连续的若干个卡片。
作用:如果一个线程修改了Region内部的引用,就必须要去通知RSet,更改其中的记录,引用的对象很多,赋值器需要对每个引用做处理,开销很大,引入卡片可解决。查找引用是可以通过卡片查找,G1对内存的使用以分区(Region)为单位,而对对象的分配则以卡片(Card)为单位。
CSet是G1垃待回收的Region集合,用于追踪存活对象,找到所有存活对象并将他们复制到空闲区域中。CSet 所有分区都会被释放,内部存活的对象都会被转移到分配的空闲分区中。
G1提供2种GC模式,分别是Young GC和Mixed GC,Full GC是大家都有的
一个Region 分为2个部分,已分配和未分配,界限叫做top,所以分配对象就是增加top的值的过程
(1)TLab中分配(线程本地分配缓冲区,ThreadLocal+CAS实现)
如果对象在共享空间中分配就要用ThreadLocal同步机制解决并发冲突问题,对象分配时在这个buff分配线程之间不用进行同步。但是线程消耗完自己buff后依然要申请新的buff也会带来并发问题,这里用CAS解决。对象过大会申请新的buff原来的有空余会浪费掉,带来碎片化问题。
(2)Eden区分配
TLab无法分配的对象才在Eden区分配,如果Eden也无法分配只能在老年代分配了
(3)H区分配
巨型对象在这里分配,无法享受Tlab带来的优化,要避免生成巨型对象。
(1)标记阶段:根扫描
根是只statis指向的对象、变量等,根引用+RSet记录的外部引用作为扫描存活对象的入口。
(2)清理阶段:对Eden区和S区垃圾回收,年轻代中没有RSet(记录了老年代到年轻代的引用)引用的会被回收
(3)对象(内存)拷贝
清理阶段完成后,GC将存活对象从Eden区和From S区拷贝到To S区,并清空Eden区和From S区,同时采用复制算法,GC将To S区和From S区角色互换。
年轻代不断进行垃圾回收活动后,为了避免老年代的空间被耗尽(会往老年代送),老年代占用空间达到默认45%时会触发一次混合垃圾回收Mixed GC,对新生代和老年代一起回收。
(需要分配老年代的对象时,但发现没有足够的空间,这个时候就会触发一次 Full GC)
Mixed GC分2步骤:并发标记、拷贝存活对象。
(1)全局并发标记
(2)拷贝存活对象
当 G1 无法在堆空间中申请新的分区时,G1便会触发担保机制,执行一次STW式的、单线程的 Full GC,Full GC会对整堆做标记清除和压缩,最后将只包含纯粹的存活对象.
G1在以下场景中会触发 Full GC:
属于并发收集阶段
(1)如果停顿时间过短的话,可能导致每次选出的回收集只占堆内存很小一部分,收集器收集的速度逐渐跟不上分配器的分配速度,进而导致垃圾慢慢堆积,最终造成堆空间占满,引发Full GC 反而降低性能。
(2)G1 内存占用、执行负载都要比CMS要高
(3)小内存的情况下使用CMS收集器,大内存的情况下可以使用G1收集器(G1收集器6GB以上)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。