剑指Offer(GC)——垃圾回收之标记算法

先来说明一个什么情况下Java对象被判定为垃圾?

当没有被其他对象引用情况下该对象就是没有用的。

判断Java对象为垃圾的算法有哪些?

  1. 引用计数法
  2. 可达性分析算法

引用计数法

通过判断对象的引用数量来决定对象是否可以被回收;每个对象实例都有一个引用计数器,被引用加一,完成引用减一;任何引用计数为0的对象实例都可以被当做垃圾收集。

优点:执行效率高,只需要过滤出引用计数为0的即可并且程序执行受影响较小
缺点:无法检测出循环引用的情况,会导致内存泄露

比如下面的示例:

class MyObject{
  private MyObject childNode;
}

class Reference{
  MyObject myObject1 = new MyObject();
  MyObject myObject2 = new MyObject();

  myObject1.childNode = myObject2;
  myObject2.childNode = myObject1;
}

上面的情况就是循环引用。

因为这个致命的缺点,现在主流的GC不采用这种垃圾收集算法进行垃圾回收。

可达性分析算法

通过判断对象的引用链是否可达决定对象是否可以被回收
可达性分析算法是从图论中提出的,把所有的引用关系画一张图,以GC Root为起点向下搜索走过的路径称之为引用链。如果一个对象在这个图中没有任何引用链出现判定为不可达,同时判定这个对象不可达可以回收掉。
在这里插入图片描述
可以做为GC Root的对象:

  1. 虚拟机栈中引用的对象(栈帧中的本地变量表):new了一个实体赋值给局部变量,在局部变量被销毁之前,new出的对象会成为GC Root;
  2. 方法区中的常量引用的对象:在类里面定义一个常量,保存的是引用对象的地址,被保存的对象成了GC Root,别的对象引用到的时候就会形成GC Root关系;
  3. 方法区中的类静态属性引用的对象
  4. 本地方法栈中JNI(Native方法)的引用对象:被引用的非Java构建的对象
  5. 活跃线程的引用对象
发布了242 篇原创文章 · 获赞 23 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44240370/article/details/104072761
今日推荐