Java垃圾回收之标记清除算法详解

java垃圾回收算法之-引用计数器,这个算法其中一个优势即是,实时性,只要对象的引用计数器的值为0,则马上回收。接下来介绍的标记清除算法,当对象的引用计数器的值为0时,不会马上被回收的。html

概念介绍java

root对象算法

在标记清除算法中,会把以下对象称之为root对象jvm

被栈中的变量(栈中存的是对象的引用)所引用的对象ide

被static变量引用的对象学习

可访问的对象spa

若是栈中有一个变量a引用了一个对象,那么该对象是可访问的,若是该对象中的某一个字段引用了另外一个对象b,那么b也是可访问的。可访问的对象也称之为orm

live

对象htm

标记清除算法介绍对象

该算法有两个阶段。

1. 标记阶段:找到全部可访问的对象,作个标记

2. 清除阶段:遍历堆,把未被标记的对象回收

备注:

该算法通常应用于老年代,由于老年代的对象生命周期比较长。

标记阶段算法

伪代码相似以下:

for each root variable r
mark (r);
sweep ();

为了可以区分对象是live的,能够为每一个对象添加一个marked字段,该字段在对象建立的时候,默认值是false

假设有一个对象p,p对象还间接的引用了其余对象,那么可使用一个递归算法去进行标记,例如:

void mark(Object p)
if (!p.marked)
p.marked = true;
for each Object q referenced by p
mark (q);

这个mark方法只有当全部对象已经被mark后才会退出。

清除阶段算法

在这个阶段,须要去遍历堆中全部对象,并找出未被mark的对象,进行回收。与此同时,那些被mark过的对象的marked字段的值会被从新设置为false,以便下次的垃圾回收。

伪代码以下:

void sweep ()
for each Object p in the heap
if (p.marked)
p.marked = false
else
heap.release (p);

下面用一张图来表示标记清除算法的整个过程。

标记清除算法的优势和缺点

1. 优势

- 是能够解决循环引用的问题

- 必要时才回收(内存不足时)

2. 缺点:

- 回收时,应用须要挂起,也就是stop the world。

- 标记和清除的效率不高,尤为是要扫描的对象比较多的时候

- 会形成内存碎片(会致使明明有内存空间,可是因为不连续,申请稍微大一些的对象没法作到),以下图:

解决循环引用

出现循环引用的代码以下:

class TestA{
public TestB b;
}
class TestB{
public TestA a;
}
public class Main{
public static void main(String[] args){
A a = new A();
B b = new B();
a.b=b;
b.a=a;
a = null;
b = null;
}
}

对应的图以下:

这个时候,当a = null; b = null;的时候,图像变成以下:

那么使用标记清除算法是能够回收a和b的,缘由是标记清除算法是从栈中根对象开始的,改算法走完后,a对象和b对象是没有被标记的,会被直接回收。

总结

以上就是这篇文章的所有内容了,但愿本文的内容对你们的学习或者工做具备必定的参考学习价值