1. 三种垃圾回收算法
1.1 标记清除
- 先沿着GC Root对象的引用链进行标记,然后清除未被标记的对象
- CMS就是采用这种回收算法(除了它几乎没别的垃圾回收器采用这种算法了)
- 会产生内存碎片。
1.2 标记整理
- 比标记清除多了整理的动作,将存活的对象向一端移动,避免内存碎片产生。
- 肯定会比标记清除慢点
1.3 标记复制
- 将内存分为两个空间,垃圾回收时将一个空间的存活对象复制到另一个空间中。
- 确定是空间利用率会低一点
- 年轻代的垃圾回收都是采用标记复制。
2. GC的分类
- 注意,GC这里特指堆内存的回收;方法区的回收成本大,有另一套机制。
2.1 Minor GC
- 发生在新生代的垃圾回收,暂停时间短。
2.2 Mixed GC
- 新生代+老年代的部分区域的垃圾回收,G1垃圾收集器特有
2.3 Full GC
- 新生代+老年代完整垃圾回收。暂停事件较长,应该尽量避免Full GC
3. 如何判断对象是否可被回收
3.1 引用计数法
- 每个对象有一个引用计数器,每当有一个对方引用了这个对象,它的计数器就会+1
- 当引用失效,计数器就会-1;如果引用计数器为0表示这个对象可以被回收了。
- 但是无法解决循环引用的问题,要解决循环引用还需要额外的机制。
3.2 可达性分析法
- 通过一系列GC Roots对象作为起点,沿着这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连的话,则表明该对象可以被回收了。
- 如何确定哪些对象可以作为GC Roots
- 虚拟机栈中引用的对象
- 本地方法栈中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- Java中用的就是可达性分析法。
- 补充的小知识
- 其实类的静态变量和静态常量都是分配在堆区。再具体点都是分配在堆区的class对象里。
- 每个类加载到JVM后都会对应生成一个class对象。而这个class对象就是分配在堆内存中的。
- 这个class对象里面就包含了该类的静态变量和静态常量。所以说,静态变量和静态常量都是分配到堆内存中的。
4. 方法区的回收
- 也叫作类的卸载
- 需要同时满足以下三个条件,而且满足了也不一定会被卸载。
- 该类的所有实例都被回收
- 加载该类的ClassLoader已经被回收。
- 该类的class对象没有被任何地方引用。(即不能通过class对象继续创建该类实例了)
5. 三色标记法
- 是可达性分析的实现
5.1 三种标记状态
- 黑色:已标记,代表该对象已经标记,并且该对象的引用对象也已经标记
- 灰色:标记中,代表该对象已经标记,但是该对象所引用的对象还没开始标记
- 白色:还未标记
5.2 什么是并发漏标
- 就是垃圾回收线程与工作线程会并发运行。
- 则在标记的过程中会发生某些对象引用关系改变。
5.4 如何解决并发漏标问题
- 方法一:增量更新法:CMS垃圾回收器所采用的方式
- 拦截每次赋值动作,只要赋值动作发生。被赋值的对象就会被记录下来。在重新标记阶段会再确认一遍
- 方法二:原始快照法:G1垃圾回收器所采用的方式
- 也是拦截每次赋值动作,但是记录的对象不同(记录新加的对象和被删除引用关系的对象),也需要在重新标记阶段对这些对象进行二次处理。
6. 常见的垃圾回收器
6.1 serial 收集器
- serial:单线程,新生代收集器
- serial old:单线程,老年代收集器
6.2 parallel 收集器
- parallel scavenge:多线程收集器,新生代收集器,标记复制算法
- parallel old:多线程收集器,老年代收集器,标记整理算法
- 均为吞吐量优先
- 工作线程与垃圾回收线程不能并发运行
6.3 CMS收集器
- 老年代收集器,标记整理,失败了还有serial old为其兜底
- 流程
- 初始标记:需要STW,垃圾回收器也是单线程运行
- 并发标记:工作线程和垃圾回收线程可以并发运行
- 重新标记:需要STW,这个很快,垃圾回收器可以多线程并行运行
- 并发清除:也可以与工作线程并发运行。
- 特点
- 吞吐量低
- 无法处理浮动垃圾
- 有空间碎片
6.4 G1收集器
- 新生代和老年代都可以回收。从整个堆空间上来说算是标记整理算法,但从局部来看是基于标记复制算法。
- 将堆划分成许多大小相等的独立区域(region),新生代和老年代不再物理隔离。
- 流程
- 初始标记:需要STW
- 并发标记
- 最终标记:需要STW。垃圾回收器可以多线程并行执行
- 筛选回收:首先对各个region中的回收价值和成本进行排序。然后根据用户所期望的GC停顿时间来制定回收计划。这个阶段可以与用户程序一起并发运行,但是因为只是回收一部分region,为了大幅度提供回收效率,一般只在这个过程运行垃圾回收线程。
- 特点
- 空间整合,不会产生内存空间碎片
- 可预测的停顿:可以选择部分region回收。