Java垃圾回收(一)

落落者难合亦难分,欣欣者易亲亦易散。

Posted by MuZhou on January 4, 2018

我们知道,在Java中内存管理是委托给虚拟机的(JVM),不像C或C++,需要手动申请及释放内存。 内存管理就涉及到内存分配和垃圾回收两个主题,前者可以参阅Java内存模型及内存分配原则,后者是本文的主要内容。
JVM在进行垃圾回收时,要解决以下三个问题:

  • 哪些对象需要回收,即判断对象存活还是死亡。
  • 什么时候进行回收,即垃圾回收的触发条件。
  • 如何进行回收,即垃圾回收算法及垃圾收集器。

哪些对象需要回收

确定哪些对象还存活,也就是确定对象是否还被引用,最简单的做法就是为每个对象加一个引用计数器,被引用时计数器加一, 引用失效时计数器减一,为零时即认定对象死亡,这就是引用计数

引用计数算法实现简单,判定效率高,但无法解决对象间循环引用的问题,因而在JVM中不使用引用计数来判定对象是否存活, 而是使用可达性分析法进行判断。

可达性分析法是选定一批对象作为GC Roots,以此为起点向下搜索,如果一个对象与GC Roots之间 不可达,则该对象可以被回收,有效的解决了循环引用的问题。

Java中GC Roots般包含以下几种对象:

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中JNI引用的对象

什么时候进行回收

垃圾回收按照回收区域一般分为Partial GC和Full GC。

  • Partial GC:不回收整个GC堆
    • Minor GC: 当年轻代eden区满时触发。
    • Major GC: 触发Major GC的情况有两种:
      1. CMS中老年代使用量超过设置的值(-XX:CMSInitiatingOccupancyFraction=)
      2. CMS中基于近期历史,维护一个预估值,预估离下一次老年代将要耗尽所剩的时间,在耗尽前进行一次Major GC。
    • Mixed GC: G1收集器独有,回收新生代和部分老年代。
  • Full GC:
    1. 永久代空间不足。
    2. System.gc()
    3. CMS中发生Concurrent Mode Failure后会使用serial collector进行一次Full GC。
    4. 老年代空间不足。

(老年代空间不足的情况如图4种) 内存分配过程

如何进行回收

垃圾回收算法

  • 标记清除: 标记对象”已死”后,清除”已死”对象。
    • 弊端: 产生不连续碎片,标记及清除两个过程效率都不高。
  • 复制:内存划分为大小相等两块,每次使用一块,复制还存活的对象到另一块,再一次性清除已使用的内存块。
    • 弊端: 可用内存缩小为一半,对象存活率高时复制操作很多。
  • 标记整理: 类同标记清除,标记后将存活对象移向一端,然后清理端边界之外的内存。
    • 弊端: 需要移动对象。
  • 分代算法: 根据对象存活周期将n内存划分为几块,根据各代特点选择最优算法。

Java中垃圾收集器基本都使用了分代算法,将内存分为新生代和老年代。对于新生代,一般采用复制算法,将新生代内存分为一块eden区, 两块同等大小Survivor区,gc时将存活对象复制到闲置的一块Survivor区。对于老年代,一般采用标记整理或标记清除算法。

垃圾收集器

在HotSpot JVM中实现了以下四种垃圾收集器:

  • Serial Collector:
  • Parallel Collector
  • CMS (Concurrent Mark Sweep) Collector
  • G1 (Garbage-First) Collector

如果按回收区域划分,可以将垃圾收集器分为以下七种: Our Collectors

垃圾收集器 区域 算法 并行 是否新特性 STW
Serial 新生代 复制算法 单线程
ParNew 新生代 复制算法 多线程
Parallel Scavenge 新生代 复制算法 多线程
Serial Old 老年代 标记整理 单线程
Parallel Old 老年代 标记整理 多线程 JDK1.6
CMS 老年代 标记清除 多线程 JDK1.5
G1 整体
  • 整体:标记整理
  • 局部:复制算法
  • 多线程 JDK1.7

    关系

    参考资料

    1. 引用计数
    2. 垃圾回收
    3. 《深入理解Java虚拟机》
    4. Java Garbage Collection Basics
    5. Concurrent Mark Sweep (CMS) Collector
    6. Our Collectors