JVM的垃圾回收机制

605 阅读3分钟

主要的垃圾回收算法

引用计数法

  • 增加引用+1,失去引用-1,只要任何一个对象引用了A,A的计数器就加1,以此类推
  • 有两个严重的问题
    • 无法处理循环引用的情况,会产生内存泄漏
    • +1 -1会对系统性能有一定的影响

标记清除算法

  • 是现代垃圾回收算法的思想基础
  • 分两个阶段,标记阶段和清除阶段
  • 缺点就是会产生空间碎片的问题

复制算法

  • 将内存分为两块,每次只使用一块内存
  • GC时将存活的内存复制到另外一快内存里,然后把第一块里面的对象都清除掉
  • 有点事效率高,缺点是每次只能用一半的内存
  • JVM中对复制算法的应用
    • 分为新生代和老年代
    • 新生代分为Eden,survive from和survive to ,每次GC都将Eden和sf里面存活的对象放到st里面,然后将sf和st转换位置
    • 什么对象放到老年代
      • BigObject
      • Oldobject 15次GC之后还存活的
      • 空间不足的时候

标记压缩算法

  • 标记存活的对象,像一端移动,然后清理所有存活对象之外的空间
  • 优点是不会产生空间碎片,也不会将内存一分为二,一般用于老年代,性价比比较高

分代算法

  • 堆空间分为新生代老年代
  • 新生代频率高,耗时短

分区算法

  • 将堆空间划分为连续的小空间
  • 每个空间独立使用回收
  • 可以控制每次回收多少个小空间,减少gc所产生的的停顿

JVM垃圾收集器

串行垃圾回收器

  • 只使用单线程进行GC
  • 独占式的GC ->stw stop the world
  • shi JVM Client模式下默认的垃圾收集器
  • 新生代用复制算法 老年代用压缩标记算法

CMS 并行垃圾回收器(将串行回收器多线程化)

  • 初始标记 STW 标记根对象
  • 并发标记所有的对象
  • 预清理
  • 重新标记
  • 并发清理 标记遗漏的对象
  • 并发重置

G1的GC收集过程

  • 优先回收垃圾比例最高的区域,G1收集器将堆划分为多个区域,每次收集部分区域来减少GC产生的停顿时间
  • 全代负责 新生代老年代

新生代GC

  • 就是新生代Eden sf st的清理

并发标记周期

  • 初始标记 STW 标记根节点
  • 根区域扫描 在survive区域里面标记可以存到老年代的对象
  • 并发标记 标记整个堆存活的对象
  • 重新标记 STW 最后的标记的阶段
  • 独占清理 STW 计算每个区块存活对象和死亡对象的比例
  • 并发清理 清理完全空闲的区域

混合收集

  • 将垃圾比例比较高的区域清理,将剩余存活对象移动到其他区域,减少内存碎片

Full GC(不是必须)

  • 内存不足的时候会触发