7-1 垃圾回收之标记算法

1,对象被判定为垃圾的标准:没有被其他对象引用。

没有被任何对象所引用,对于系统而言,它就是垃圾,其占据的内存就要被释放,同时此对象也要被销毁。

2,判断对象是否为垃圾的算法

(1)引用计算算法
(2)可达性分析算法

3,引用计算算法

判断对象的引用数量

  • 通过判断对象的引用数量来决定对象是否可以被回收;
  • 堆中每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1;
    当一个对象被创建时,若该对象实例分配给一个引用变量,该对象实例的引用计数器就会被设置为1,若该对象又被另外一个对象所引用,则该对象的引用计数器继续+1,也就是变为2,而当该对象实例的某个引用超过了生命周期,或者被设置为一个新值时,该对象实例的引用计数器便会-1,比如在某个方法里,定义了一个引用变量,指向该对象实例,当方法结束的时候,由于该引用变量(该变量是存储在虚拟机上的)是局部变量,方法结束后会被自动干掉,此时,该实例对象的引用计数器便会-1。
  • 任何引用计数为0 的对象实例可以被当作垃圾收集;

优点:执行效率高,程序执行受影响较小(我们只需过滤出引用计数器为0的对象,将其内存回收即可,可以交织在程序运行中。那由于垃圾回收的时候,可以做到几乎不打断程序的执行,因此对程序需要不被长时间打断的实时环境比较有利)
缺点:由于实现过于简单,会出现无法检测出循环引用的情况,导致内存泄漏(比如,父对象有对一个子对象的引用,子对象反过来引用父对象,这样它们的引用计数器永远不可能为0)。
正是因为这个短板,虽然Java语言规范没有明确地说明JVM使用哪种垃圾收集算法,但是从表现来看,主流的Java垃圾收集器并未采用此种机制去判断对象是否为垃圾,而用的是下面这种算法,去对垃圾对象进行标记。

4,可达性分析算法

通过判断对象的引用链是否可达来决定对象是否可被回收。
可达性算法,是从离散数学中的图论引入的。程序把所有的引用关系,看作一张图,通过一系列名为GC ROOT对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径就被称为引用链,即:Reference chain。当一个对象从GC ROOT没有任何引用链相连,那从图论上来说,从GC ROOT到这个对象是不可达的,那在这个时候,就证明这个对象是不可的,那他就被标记为垃圾了。如下图:
垃圾回收器会对内存中整个对象图进行遍历,回收器将访问到的所有对象标记为存活,图中标记为蓝色,不可达的对象的标记为灰色,标记为灰色的对象会被回收器清除掉。
在这里插入图片描述

5,可以作为GC ROOT的对象

  1. 虚拟机栈中引用的对象(栈帧中的本地变量表);
    比如说,我们在Java方法里new了一个Object,并赋值给了一个局部变量,那在该局部变量没有被销毁之前,new出的这个Object就会成为GC ROOT。
  2. 方法区中的常量引用的对象;
    比如,在类里面定义了一个常量,而该常量保存的是某个对象的地址,那么被保存的对象,也成了GC的根对象,当别的对象引用到它的时候,就会形成引用链。
  3. 方法区中的类静态属性引用的对象(原理同2);
  4. 本地方法栈中JNI(Native方法)的引用对象;
    咱们调用Native的方法及被引用的通过非Java语言构建的对象,也可以成为GC ROOT。
  5. 活跃线程的引用对象。
    Java万物,皆为对象,因此,活跃的线程,也会成为GC ROOT。只要线程还处于活跃状态,它引用的对象,也被判为可达。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值