CMS垃圾回收器

  • 老年代回收器
  • 标记清理算法(产生碎片)
  • 初始标记(STW)- 并发标记 - 重新标记(STW)- 并发清理

CMS和G1垃圾回收器_加锁

  • 整堆收集​​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)

CMS和G1垃圾回收器_对象复制_02

  • 三种回收模式
  • ​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使用颜色指针解决)