> For the complete documentation index, see [llms.txt](https://gitbook.fantasticmao.cn/tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gitbook.fantasticmao.cn/tech/java/jvm/la-ji-hui-shou-suan-fa.md).

# 垃圾回收算法

## 引用计数算法

### 基本思路

在对象中添加一个引用计数器，每当有一个地方引用它时，计数器值就加一；当引用失效时，计数器值就减一；任何时刻，计数器值为零的对象就是不可能再被使用的。

### 优点/缺点

引用计数算法的原理简单，执行高效，但是主流的 Java 虚拟机中都没有选择引用计数算法来进行内存管理，主要原因是这个看似简单的算法其实有很多例外情况需要考虑，必须配合大量额外处理才能保证算法正常地工作，例如在涉及对象之间互相循环引用的问题。

### 经典案例

Netty 中的 `ByteBuf` 使用了引用计数算法，提供了优于 JVM GC 和引用队列的高效的实时性。

## 可达性分析

### 基本思路

当前主流程序语言的内存管理都是通过可达性分析（Reachability Analysis）算法来判定对象是否存活的。

通过一系列的「GC Roots」的根对象作为起始节点，从这些节点开始根据引用关系向下搜索，搜索过程所走过的路径被称为「引用链（Reference Chain）」，如果某个对象到 GC Roots 间没有任何引用链相连，或者用图论的话来说就是从 GC Roots 到这个对象不可达，则证明此对象是不可能再被使用的。

```
      GC Roots
-----------------------------------------------
	      |
	   object1                  object5
    /       \                /       \
object2   object3        object6   object7
             |
          object4
```

在 Java 技术体系中，固定可作为 GC Roots 对象包括以下几种：

* 在虚拟机栈中引用的对象，例如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等；
* 在方法区中类的静态属性引用的对象，例如 Java 类的引用类型的静态变量；
* 在方法区中常量引用的对象，例如字符串常量池中的引用；
* 在本地方法区中 JNI 引用的对象；
* 在 Java 虚拟机内部的引用，例如基本数据类型对应的 Class 对象，一些常驻的异常对象，系统类加载器等；
* 所有被同步的锁（synchronized 关键字）持有的对象；
* JMXBean、JVMTI 中注册的回调、本地代码缓存等
* ......
