JVM

深入理解 Java 虚拟机之垃圾回收

深入理解 Java 虚拟机之垃圾回收

Posted by 月光下的海 on October 1, 2021

深入理解 Java 虚拟机之垃圾回收

对象是否存活(何时需要被回收)的判定

引用计数算法

给对象分配一个计数器,当有一个地方引用该对象时,计数器值+1,当引用失效时-1.当值为0时表示该对象不再被使用,进行回收。

优点:实现简单、效率较高

缺点:难以解决循环引用问题

可达性分析算法
  • 通过一系列称为 GC Roots 的对象为起始点往下搜索,经过的路径称为引用链 Reference Chain,当没有任何引用链相连时,认为此对象不可达,进行回收。
  • GC Roots 对象包含以下几种:
    • 虚拟机栈(栈帧中的本地变量表)中引用的对象
    • 方法区中静态属性引用的对象
    • 方法区中常量引用的对象
    • Native方法引用的对象

垃圾回收算法

标记-清除算法(Mark-Sweep)- 用于老年代
  • 分为标记-清除两步。缺点:效率不高;容易产生内存碎片
复制算法(Copying)- 一般在新生代中使用
标记-整理算法(Mark-Compact)- 用于老年代

垃圾回收器

Serial 收集器
  • 单线程收集器,会Stop The World(暂停其他所有的工作线程造成系统停顿)-新生代收集器
Serial Old 收集器
  • Serial 收集器的老年代版本
ParNew 收集器
  • Serial 收集器的多线程版本 -新生代收集器
ParNew Scavenge 收集器
  • 新生代收集器,更关注于吞吐量
Parallel Old 收集器
  • ParNew Scavenge 收集器的老年代版本
CMS 收集器 (Concurrent Mark Sweep)
  • 目标是保证垃圾回收时的停顿时间最短,整体分为四个步骤:
    • 初始标记
    • 并发标记
    • 重新标记
    • 并发清除

      缺点:

      • 对CPU资源较敏感(在并发阶段,由于占用部分CPU资源,会导致应用程序响应速度变慢、吞吐量下降)
      • 无法处理浮动垃圾(指在并行清理阶段用户线程执行过程中产生的新的垃圾,CMS 收集器无法在本次 GC 中处理掉只能留到下一次 GC )
      • 易产生内存碎片
G1 收集器
  • 并行与并发
  • 分代收集
  • 空间整合
  • 可预测的停顿

内存分配策略

  • 对象优先在新生代的 Eden 区分配

  • 大对象直接进入老年代

  • 长期存活的对象进入老年代

    每个对象有对应的年龄计数器。如果在Eden 出生,经过第一次Minor GC后仍然存活,移动到Survivor区,年龄会设为1,此后每在到 Survivor 区经过一次 Minor GC 后年龄会+1,当增加到(默认15)时,会被移动到老年代。