找寻garbage的两种方式 ---- 引用计数法与根可达算法。
引用计数法:为每个对象添加一个引用计数器,用于统计指向该对象的引用数量,假设某个对象的引用数量为0,则说明该对象没有引用,视为垃圾。

引用计数法存在一个缺陷:当存在循环引用的时候,每个对象的计数器都大于0,视为存活对象,但是这几个循环引用外界没有指向这一部分,本应该视为垃圾回收的。存在内存泄漏问题
根可达算法:由GCRoot作为起点,向下搜索,查询对象是否被引用过,以判断对象是否存活。

根可达算法可以避免引用计数法存在的问题,防止漏标现象。
GCRoot对象:根对象(从程序运行就始终保持存活的对象)
● 虚拟机栈中引用的对象(栈帧中的本地变量表)
● 方法区中类静态属性引用的对象
● 方法区中常量引用的对象
● 本地方法栈中JNI(Native方法)引用的对象
垃圾回收的几种方式 ---- 标记清除(Mark-sweep)、拷贝算法(Copy)、标记压缩(Mark-Compact)
1、标记清除

标记清除需要扫描两次内存:第一次扫描标记出所有存活的对象,第二次扫描,清除所有未被标记的对象(垃圾)。清除之后会产生内存的碎片化空间。适用于存活对象较多的情况。
2、复制算法

复制算法只需要一次扫描,找到不可回收的对象,复制到另一半区域,内存浪费,适用与存活对象较少的情况,比如年轻代,S1,S2区域。
3、标记压缩

标记压缩需要两边扫描,标记不可回收的对象,将不可回收的对象copy到前面可回收的位置(压缩),没有碎片化,也不存在浪费空间的问题,适用于垃圾较少的情况(存活对象多),比如老年代。