1、GC分类
(1)部分收集(Partial GC)
新生代收集(Minor GC/Young GC):只对新生代进行垃圾收集。(读音[ˈmaɪnə(r)])
老年代收集(Major GC/Old GC):只对老年代进行垃圾收集。(读音[ˈmeɪdʒə(r)])
混合收集(Mixed GC):对整个新生代和部分老年代进行垃圾收集。
(2)整堆收集(Full GC)
收集整个Java堆和方法区。
2、死亡对象判断方法
(1)引用计数法
给对象中添加一个引用计数器:每当有一个地方引用它,计数器就加1;当引用失效,计数器就减1;任何时候计数器为0的对象就是不可能再被使用的。
这个方法实现简单,效率高,但是目前主流的虚拟机中并没有选择这个算法来管理内存,其最主要的原因是它很难解决对象之间相互循环引用的问题。
(2)可达性分析算法
这个算法的基本思想就是通过一系列的称为“GC Roots”的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连的话,则证明此对象是不可用的,需要被回收。
即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对象死亡,至少要经历两次标记过程。
3、垃圾收集算法
(1)标记-清除算法
首先标记出所有不需要回收的对象,在标记完成后统一回收掉所有没有被标记的对象。
效率问题,标记和清除两个过程的效率都不高。空间问题,标记清除后会产生大量不连续的碎片。
(2)标记-复制算法
将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。
(3)标记-整理算法
标记过程与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。
(4)分代收集算法
据各个年代的特点选择合适的垃圾收集算法。
比如在新生代中,每次收集都会有大量对象死去,所以可以选择”标记-复制“算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。
4、垃圾收集器
垃圾收集器就是内存回收的具体实现。
(1)Serial收集器
单线程收集器,只会使用一条垃圾收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集工作的时候必须暂停其他所有的工作线程("Stop The World"),直到它收集结束。
新生代采用标记-复制算法,老年代采用标记-整理算法。
简单而高效。
(2)ParNew收集器
ParNew收集器其实就是Serial收集器的多线程版本。
新生代采用标记-复制算法,老年代采用标记-整理算法。
(3)Parallel Scavenge收集器
多线程收集器。
Parallel Scavenge收集器关注点是吞吐量(高效率的利用CPU)。
新生代采用标记-复制算法,老年代采用标记-整理算法。
JDK1.8默认使用的是Parallel Scavenge和Parallel Old。
(4)Serial Old收集器
Serial收集器的老年代版本。
(5)Parallel Old收集器
Parallel Scavenge收集器的老年代版本。
(6)CMS收集器
CMS收集器是一种以获取最短回收停顿时间为目标的收集器。
CMS收集器是HotSpot虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。
主要优点:并发收集、低停顿。
主要缺点:对CPU资源敏感;无法处理浮动垃圾;它使用的回收算法“标记-清除”算法会导致收集结束时会有大量空间碎片产生。
(7)G1收集器
G1是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器。以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征。