CMS垃圾回收器
- 老年代回收器
- 标记清理算法(产生碎片)
- 初始标记(STW)- 并发标记 - 重新标记(STW)- 并发清理
- 整堆收集
Minor GC
或Major GC
优点:
- 并发标记和清理支持并发,低停顿
缺点:
- 并发阶段占用系统部分资源
- 无法处理浮动垃圾(并发标记阶段用户线程产生),只有等到下一次收集才能处理,可能出现在一次并发收集没完成过程,用户申请内存空间不足,触发
fullGC
- 标记-清理算法产生碎片无法利用,当无法为大对象分配连续空间产生
Con-current Mode Failure
,触发FullGC
,需要开启CMS
内存整理,但停顿时间延长
G1 - GarbageFirst
- 年轻代和老年代混合回收器
- 内存分区
region
(默认分2048
份),年轻代和老年代都是分配在Region
中,但做了区分 - 收集的最小单位
Region
- 年轻代分为:
Eden
和Survivor
,老年代分为:old
和 homongous
(分配大对象)
- 一个对象占用的空间超过内存分段Region的一半分配到
humongous
中 - 若是对象的大小超过一个甚至几个分段的大小,则对象会分配在物理连续的多个
Humongous
分段上
- 使用记忆集避免全堆作为
GC Roots
扫描,每个Region
都维护有自己的记忆集,这些记忆集会记录下别的Region
指向自己的指针,并标记这些指针分别在哪些卡页的范围之内。G1
的记忆集在存储结构的本质上是一种哈希表,Key
是别的Region
的起始地址,Value
是一个集合,里面存储的元素是卡表的索引号的“双向”的卡表结构,可能会占整个堆容量的20%
乃至更多的内存空间 - 标记 - 整理算法(实际为
Region
之间复制) - 支持可预测的停顿
- 初始标记(STW) - 并发标记 - 最终标记 (STW) - 筛选回收(STW)
- 三种回收模式
-
Young GC
:eden region
被耗尽没法申请内存时,就会触发 -
Mixed GC
:当老年代大小占整个堆大小百分比达到该阈值时,会触发 -
Full GC
:对象内存分配速度过快,mixed gc
来不及回收触发
-
TLAB
线程本地分配缓冲区
- 每个应用程序的线程会被分配一个
TLAB
。TLAB
中的内存来自于G1
年轻代中的内存分段。当对象不是Humongous
对象,TLAB
也能装的下的时候,对象会被优先分配于建立此对象的线程的TLAB
中。这样分配会很快,由于TLAB
隶属于线程,因此不须要加锁
-
PLAB
G1
回收线程分配缓冲区
-
G1
会在年轻代回收过程当中把Eden
区中的对象复制(“提高”)到Survivor
区中,Survivor
区中的对象复制到Old
区中。G1
的回收过程是多线程执行的,为了不多个线程往同一个内存分段进行复制,那么复制的过程也须要加锁。为了不加锁,G1
的每一个线程都关联了一个PLAB
,这样就不须要进行加锁了
优点:
- 没有空间碎片
- 可以分析预测回收时间,并设置期望停顿时间,制定相应回收计划
- 非整区收集,筛选
Region
回收
缺点:
- SATB(snapshot at the begining)把白放入栈中,标记过程是和应用程序并发运行的(不须要STW) 这种方式会形成某些是垃圾的对象也被当作是存活的,因此G1会使得占用的内存被实际须要的内存大。
- 卡表占用空间过大(ZGC使用颜色指针解决)