垃圾收集算法
前言
开始之前,首先先了解一下对象回收等相关知识
(一) 对象回收
(1)判断对象是否存活
1.引用计数算法
给对象中添加一个引用计数器,每当有一个地方引用此对象,计数器就加1;当引用失效时,计数器就减1。计数器值为0的情况下,对象就不可被使用。
缺点:很难解决对象之间的相互循环引用的问题。
2.根搜索算法
通过GC Roots的对象作为起始点,从这些节点开始往下面搜索,搜索所走过路径,称为引用链,当一个对象到GC Roots没用任何引用链,证明次对象不可用(根可达性分析)。
GC Roots包括:
- 虚拟机栈(栈帧中本地变量表)的引用的对象
- 方法区中的类静态属性引用的对象
- 方法区中的常量引用的对象
- 本地方法栈中的JNI(native方法)的引用的对象
(2) 引用分类
1. 强引用
类是于“Object object = new Object()“ 这类引用,属于强引用。
垃圾收集器永远不会回收掉被强引用的对象,只有当obj这个引用被释放之后,对象才会被释放掉。
2. 软引用
Object object = new Object()
SoftReference<Object> sf = new SoftReference<Object>(obj);
非必须引用,内存溢出之前进行回收,软引用主要用户实现类似缓存的功能,在内存足够的情况下直接通过软引用取值,无需从繁忙的真实来源查询数据,提升速度。
3. 弱引用
Object object = new Object()
WeakReference<Object> wf = new WeakReference<Object>(obj);
wf.get();//有时候会返回null
wf.isEnQueued();//返回是否被垃圾回收器标记为即将回收的垃圾
弱引用是在第二次垃圾回收时回收,短时间内通过弱引用取对应的数据,可以取到,当执行过第二次垃圾回收时,将返回null。
弱引用主要用于监控对象是否已经被垃圾回收器标记为即将回收的垃圾,可以通过弱引用的isEnQueued方法返回对象是否被垃圾回收器标记。
4. 虚引用
Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj);
虚引用是每次垃圾回收的都会被回收,通过虚引用主要用于检测对象是否从内存中删除。
(3) 回收对象
在根搜索算法中不可达的对象,至少要经历俩次标记过程;如果对象在进行根搜索发现没有与GC Roots相连接的引用链,那么它将会被标记第一次并且进行一次筛选,筛选的条件是此对象是否有必要进行finalize()方法。
1.若对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过了,此时就不需要执行finalize();
2.若对象被判定为有必要执行finalize()方法,此时这个对象将会放置在F-Queue的队列中,根据优先级执行。
(二)垃圾收集算法
(1)标记-清除
标记清楚法,是最基础的收集算法,算法分为标记,清除俩个阶段;首先是先标记需要回收的对象,在标记统计完成之后,回收清除之前所有标记对象。
它主要有俩个缺点:1.效率问题,效率会比较低下,2.空间问题,标记清除后会产生很多不连续的内存碎片。如下图:
(2)复制
将内存划分为大小相同的俩块,每次只使用其中的一块;当第一块的内存使用完毕之后,就会把第一块中存活的对象,复制到第二块上,然后再把已使用的内存空间清理调。然后移动对顶指针,按顺序分配内存,缺点:在对象存活数量较多的情况下,需要执行多次复制操作,效率将比较低,如果是1:1,空间比较浪费,如下图:
基于上图,目前再JVM中在Young区进行垃圾回收时,采用这种算法,因为在Young区,98%的对象都会死亡。可以不用设置1:1的比例。而是设置Eden为内存较大的一块,survivor为内存较小的俩块(S0,S1)。
当回收的时候,将Eden和servivor中存活的对象复制到另外一块survivor区中。HotSpot虚拟机默认的Eden和survivor比例为:8:1, Young区新生代容量为90%,只有10%的空间暂时未使用,这样利用率就比较高。
(3)标记-整理
上面介绍复制算法的缺点,后面就出现了,标记整理算法。也是先标记需要回收的对象,然后让所有存活的对象向一段移动,然后直接清理边界以外的内存。如下图:
(4)分代回收算法
目前,大多数虚拟机不管是IBM,还是Sum采用分代回收的算法。在HotSpot虚拟机中,Young区采用复制算法,Old区采用标记整理/清楚。刚刚已经介绍,复制算法在Young区使用;old因为存活的对象年龄(垃圾回收次数,jvm默认15次)都是比较大的,所以回收时,很少对象死亡。
(5)垃圾收集器
接下来,简单讲一下垃圾收集器,后续文章会对垃圾收集器进行详细的介绍:
P.S:Serial New收集器是针对新生代的收集器,采用的是复制算法
Parallel New(并行)收集器,新生代采用复制算法,老年代采用标记整理
Parallel Scavenge(并行)收集器,针对新生代,采用复制收集算法
Serial Old(串行)收集器,新生代采用复制,老年代采用标记整理
Parallel Old(并行)收集器,针对老年代,标记整理
CMS收集器,基于标记清理
G1收集器:整体上是基于标记 整理 ,局部采用复制(当前流行的收集器)