CMS
整体使用标记清除算法, 所以很容易产生内存碎片, 从而引起FULL GC, 又因为FULL GC 是Serial Old 是单线程, 全部堆STW所以哼慢很卡
大体步骤:
1. 初始标记 标记直接能与根之间关联的对象
2. 并发标记
3. 重新标记 在并发标记区间可能会出现漏标等现象, 处理通过写屏障完成(就是会将写操作记录下来)
4. 并发清除 由于是并发清除, 所以垃圾回收和用户线程同时产生, 所以可能会产生浮动垃圾
mark 算法采用三数扫描算法
1. 自己被标记, 子对象被标记, 就是黑色, 遇到黑色就停止扫描
2. 自己被标识, 子对象没被标识, 就是灰色
3. 没有被标记就是白的
因为是并发标记, 所以有可能造成, 漏标(存活对象没有被标记), CMS 采用写屏障来完成
CMS 在逻辑和物理上都是分区的
G1
garbage first 垃圾优先, 优先根据清除垃圾最多的region , 从而可以高效的达到用户所期望的停顿时间
物理上已近不在分代, 但逻辑还是分代
整体上采用标记整理算法, region之间通过复制存过对象到新region
分为老年代, 新生代, H区(大对象分配, 超过region的一半), 未分配的region, 每个region(1~32M)
新生代算法:
1. 根扫描
2. 更新dirty card RSet
3. 拷贝对象
4 处理引用对象
Mixed GC
1. 初始标记
2.根区域扫描
3. 并发标记
4. 重新标记
5, 清理
mark算法:
STAB (再开始的时候使用快照), 写屏障, 三色标记算法
一般mixed GC 都在young GC后面复用根扫描
Rset: 每个region都有的, 记录谁引用了我, 这样young GC的时候就不用扫描老年代, 所以一般在新生代和老年代之间的region记录
dirty card : 不是空白的就是脏的
Cset: 记录要被回收region的对象, 在Cset集合中回收存活下来的还是会分配到新生代或者晋升到老年代
young GC 一般是在什么时候发生的---> 一把是在eden Region分配达到上限的时候分配
mixed GC : 一般是在region的使用率达到一定的界限的时候, 触发
Full GC; 对象复制时候, 新Region分配不到了, 分配大对象时候失败(没有连续的空间)
并发预处理就是在remark, 之前调用minor GC, 使得remark的内容减小