# JVM学习笔记 垃圾回收

- URL: https://www.yidoo.xyz/jvm-garbage-collection
- 作者: 核动力蜗牛
- 发布时间: 2013-04-07
- 更新时间: 2013-04-07
- 分类: 技术笔记
- 标签: jvm

# 判断对象是否存活

**1）引用计数算法（Reference Counting）**  
     给对象中添加一个引用计数器，每当一个地方引用它时计数器+1,；当引用失效时，计数器-1；任何时刻计数器为 0 的对象就是不可能再被使用。  
    举例：Python，Flashplayer，COM  
    缺陷：无法解决对象之间的循环引用问题。

**2）根搜索算法**
以 GC Roots 作为起点，从这些节点开始向下搜索搜索所走过的路径称为引用链（Reference Chain），当一个对象到 GC Roots 没有和任何引用链相连（也可以理解为图论中的该节点不可达），则该对象是不可用的。  
    Java 中，可以作为 GC Roots 的对象包括：  
    ①Stack 中（Stack Frame 的本地变量表）中的引用对象。  
    ②Method Area 中的静态属性引用对象和常量引用对象。  
    ③Native Method Stack 中 JNI 的引用对象。

# 引用

**1）强引用（Strong Reference）**：类似“Object obj=new Object()”这类的引用，只要强引用存在 GC 就不会收回被引用的对象。  
**2）软引用（Soft Reference）**：对于软引用的对象，在系统将要发生内存溢出之前，将会把这些对象列进回收的范围，进行第二次回收。如果还没有足够的内存，就会抛出内存溢出异常。  
**3）弱引用（Weak Reference）**：被弱引用关联的对象只能保留到下一次垃圾回收发生之前。  
**4）虚引用（Phantom Reference）**：被虚引用的对象，完全不会影响其生存时间构成，也无法通过虚引用取得一个实例。虚引用的唯一目的就是在对象被 GC 回收时可以收到一个通知。

# 垃圾收集算法

**1）标记-清除算法**
    首先标记出所有需要回收的对象，在标记完成后统一回收掉所有被标记的对象。  
    优点：简单  
    缺点：效率低下，且容易产生不连续的区域  
**2）复制算法**
    将内存空间分为 Eden 和 Survivor 两块区域，当一块区域内存用完时，将存活的对象复制到另一块区域，然后把之前的区域清理掉。  
    优点：简单高效，不会产生不连续的区域  
    缺点：内存利用率只有 50%  
**3）标记-整理算法**
    相比标记-清除算法，在标记之后并不马上进行回收，而是将存活的对象向一端移动，然后清理掉端外内存。  
**4）分代收集算法**
    将 Java Heap 分为新生代（Younger Generation）和老年代（Tenured Generation），根据各个年代的特点采用最适合的收集算法。
