设计架构的重要思想
分治
分层
吞吐量G1比PS降低10%~15%
追求耗时少,200ms内有响应,用G1
追求throughput,用Parallel
G1原理模型
humongous object
超过单个region50%
GC何时触发
YGC
Eden空间不足
多线程并行执行
FGC
Old空间不足
system.gc()
G1特点
并发收集
压缩空闲空间不会延长GC的暂停时间
更易预测的GC暂停时间
适用不需要实现很高的吞吐量的场景
动态新老年代比例:5%~60%,不需要手工指定
G1预测停顿时间的基准
Card Table
YGC的时候,需要扫描整个Old区域,效率非常低,所以Jvm设计了CardTable
如果一个CardTable中有对象指向Y区,将其设置为Dirty,下次扫描时,只需要扫描Dirty的Card Table
在结构上,Card Table用Bitmap实现
G1的内存区域不是固定的Eden或者Old
G1基本概念
CSet
CSet = Collection Set
一组可被回收的分区的集合
在CSet中存活的数据会在GC过程中被移动到另一个可用分区
CSet中的分区可以来自Eden空间、survivor空间或者老年代
Cset会占用不到整个堆空间的1%大小
Rset
RememberedSet(G1高效回收的关键)
Region中都有一个HashSet(Rset),记录其他对象对本对象的引用
回收高效,占用空间变大,空间换时间
G1中的MixedGC
相当于一个CMS
XX:InitiatingHeapOccupacyPercent
默认值45%
当O超过这个值时,启动MixedGC
MixedGC过程
初始标记stw
并发标记
最终标记(重新标记)
筛选回收stw(并行)
初始标记
并发标记
最终标记
并行筛选回收(筛选垃圾最多的region进行回收)
如果G1产生FCG,应该怎么做
扩内存
提高CPU性能(回收得快,业务逻辑产生对象速度固定,垃圾回收快,内存空间大)
降低MixedGC触发的阈值,让MixedGC提早发生(默认45%)
阿里多租户Jvm
每租户空间
session based GC
并发标记算法
在标记对象过程中,对象的引用关系正在发生改变
三色标记
白色,未被标记的对象
灰色,自身被标记,成员变量未被标记
黑色,自身和成员变量均已标记完成
漏标
A指向D,B指向D的引用消失了
产生漏标
漏标指的是,live object,由于没有遍历到,被当成garbage回收
标记进行时增加了一个黑到白的引用,如果不重新处理黑色,会漏标
标记进行时删除了灰对象对白对象的引用,这个白对象可能被漏标
漏标解决方法
incremental update(CMS采用方案)
增量更新,关注应用的增加,把黑色重新标记为灰色,下次重新扫描属性
SATB snapshot at the beginning(G1采用方案)
关注引用删除,当B->D消失时,要把这个引用推到GC的堆栈,保证D还能被GC扫描到
为什么G1使用SATB
灰色->白色,引用消失时,如果没有黑色指向白色
引用会被push到堆栈,下次扫描时拿到这个引用,由于RSet的存在
不需要扫描整个堆区查找指向白色的引用,效率比较高
SATB配合RSet,完美搭配
Rset与赋值效率
由于RSet的存在,每次给对象赋引用时候,就得做一些额外操作
在Rset中做一些额外的记录(在GC中称为写屏障)
写屏障(不是内存屏障)
No Sivler Bullet
原文:https://www.cnblogs.com/YC-L/p/14418930.html