# GC垃圾回收

## 垃圾回收

> * 哪种内存需要回收？
> * 什么时候回收？
> * 怎么回收？

## 如何判断一个对象可以回收？

> 可达性分析算法

通过一个`GC Roots`的对象向下查找，整个搜索路径叫做引用链，当一个引用链没有 任何`GC Roots`说明可以回收了

可以作为GC-Roots的对象

* 方法区中静态变量所引用的对象
* 虚拟机栈中所引用的对象

> 引用计数法

每当有一个对象被引用时，引用计数器就+1，当失效时就-1，什么时候为0说明就可以回收了， `无法解决循环引用的问题`

## 怎么回收？

### 标记清除算法

将`不需要回收的对象`做一个标记，然后清除可以回收的对象

* 标记和清除的效率不高
* 容易产生不连续的内存

### 复制算法(新生代)

复制算法是将内存划分为两块大小相等的区域，每次使用时都只用其中一块区域， 当发生垃圾回收时会将存活的对象全部复制到未使用的区域，然后对之前的区域进行全部回收。 浪费内存，在[jvm内存划分](https://lxs-shmily.gitbook.io/java-notes/jvm/jvm-biao-zhun)中的堆内存的新生代中就是用的复制算法

### 标记整理算法 (老年代)

原理和`标记清除算法`类似， 只是最后一步的清除改为了将存活对象全部移动到一端，

### 分代回收算法

现代多数的商用 JVM 的垃圾收集器都是采用的分代回收算法，和之前所提到的算法并没有新的内容。
