整体: 标记-整理
Regin之间: 标记-复制
↑这也是对CMS的一个优势, 没碎片,有利长期运行
JDK9后成为默认收集器
面向服务端应用的, 期望替代CMS(同样都以停顿时间为目标)
软实时垃圾收集器:
尽量达到不超过设定的毫秒停顿时间
Regin

大小相等的Regin, 都平等,是垃圾收集的最小单元,
不同角色
可以感觉需要扮演Eden,Servivor,老年代,H区域(放超过一半的大对象),
不同的角色能用不同的策略
回收集
跟踪Regin的垃圾收集价值(按经验估计能收到多少,要停顿多久)
维护一个优先级列表
每次,根据用户设定的希望停顿的世界, 优先收集价值大的Regin
G1 解决了这些技术难题才诞生
记忆集
只分为新生代,老年代, 只要在新生代有个卡表,每个字节代表一卡页(老年代一小块内存), 是不是有对新生代对象的引用就好了
G1每个Regin都维护各自的记忆集,记录另外的某Regin(起止位置来确定Regin),的卡表
因为有更加大额为内存占用
并发
并发标记不误收 是 用原始快照
实现的
每个Regin有2个指针, 之间的区域用于 并发中产生的新对象, 不纳入回收范围
如果不够用, 和CMS一样, 会 Full GC,STW
停顿预测模型
以衰减均值
为理论基础
就是,比平均值 更容易 受到新数据影响
最近的数据更加有决定性
步骤
其实只有第二步 并发标记
是并发

1.初始标记(短STW, 并且其实无额外耗时)
和CMS的初始标记一样的, 就标记一下GC Roots 直接关联到的对象,
本来耗时就短, 加上Minor GC时候同步完成, 实际上没有额外停顿
2.并发标记
名字和 CMS一样, 但是避免并发时的修改造成的误杀, 用的是 原始快照
,而不是增量更新
3. 最终标记(短STW)
CMS叫重新标记
最终标记就是处理原始快照
的后续
4.筛选回收(长STW)
更新Regin统计数据,
按价值和成本给Regin排序
按用户期望停顿时间, 决定回收集
把活着的复制到空Regin(标记-复制)
目标停顿时间 设置的建议
默认是200毫秒的目标,
调这个可以 平衡 吞吐量Vs延迟
100~300 比较合理
如果太低的话, 每次只能回收没几个Regin, 到时候空间不够用 会Full GC , 反而降低性能
和CMS 比的缺点
内存占更多
为了垃圾回收占的内存很多, 记忆集每个Regin都要有, 并且会占到20%甚至以上,
不像CMS 只要新生带保留一份对老年代的卡表就行了
执行负荷大
写后屏障 更新卡表2个都有, G1更繁琐
写前屏障, 只有G1有, 因为要原始快照
来实现并发标记, 虽然减少了最终标记的停顿太长
经验:大内存还是G1好 6~8G内存就G1好了
网友评论