垃圾回收标记阶段算法

1.标记阶段的目的

主要是在GC在前,判断出哪些是有用的对象,哪些是需要回收的对象,只有被标记为垃圾对象,GC才会对其进行垃圾回收。判断对象是否为垃圾对象的两种方式:引用计数算法 和可达性分析算法。

2.引用计数算法(现在不再使用)

引用计数算法实现相对比较简单,就是给每一个对象保存一个引用计数器,记录此对象被引用的次数。只有该对象的引用次数为0,才表示该对象不在被使用,即可回收。

优点:便于实现,回收及时,判定效率高。

缺点:

  • 因为要有引用计数器,所以需要额外的空间。

  • 每次的操作都要个计数器重新赋值,所以需要额外的时间。

  • (重点)无法处理循环引用的问题,比如说外部P引用了A,而A引用了B,B又引用了C,C又引用了A,那么对于A,B,C其计数器为2,1,1,那么此时如果外部引用P赋值为null,及无外部引用了,但是A,B,C计数器依然为1,无法被回收,常此就会出现内存泄露。

3.可达性分析算法(也称为根搜索算法、追踪性垃圾收集)

可达性算法可以解决循环引用的问题 ,其思路为以根为起始点向下搜索 ,存活的对象就是与根直接或者间接相连的对象 ,所搜索经过的路径称为引用链,如果未被搜索到,则表明不可达,就标记为垃圾对象。

那么要作为根的判断标准是什么呢?

  • 虚拟机栈中引用的对象(如局部变量...)。

  • 方法区中类的静态变量。

  • 被同步锁synchronized持有的对象。

  • Java虚拟机内部的使用。

4.对象的finalization机制

finalize()方法机制,是指对象被回收前由GC调用 的方法,只会调用一次 ,Java提供了对象被销毁前允许开发人员来自定义销毁前要做的事情,finalize()方法是Object类中的方法,此方法内没有任何的实现,开发人员可以重写该方法。不要主动的去调用finalize()方法。因为:

  • finalize()方法可以使对象不在被销毁,在临死前拉一把。

  • 如果不发生GC,finalize方法是没有执行机会的。

  • 一个糟糕的finalize()可能会使程序崩溃,比如里面自定义一个死循环。

5.由于finalize(),对象的三种状态

  1. 可触及的,及可从根到达此对象。

  2. 可复活的,对象被标记为垃圾,但是可能在finalize()方法中被拯救。

  3. 不可触及的,对象的finalize()方法被调用了,并且没有复活。

具体的过程:一个对象要被回收,要经历两次标记的过程,如果此对象没有任何的引用,则会被标记为垃圾对象,等待回收,在回收前,执行该对象的finailze()方法,如果没有重写该方法,对象就会为不可触及状态被清理,如果重写了该方法,则会被加入到队列中,由一个Finalizer低优先级的线程来执行,如果在方法中没有补救,那么第二次标记就会标记该对象将会彻底被回收清理,如果在finalize()方法中对象又建立了联系,那么此对象又会进入可触及的状态,如果又没有了引用,finalize()方法不会在被调用(只会调用一次),对象直接会变为不可触及的状态。

相关推荐
码爸8 小时前
线性回归算法
算法·机器学习·线性回归
Coder-magician8 小时前
《代码随想录》刷题打卡day51:图论-part09(dijistra堆优化,Bellman_ford算法)
算法·图论
Nil2088 小时前
leetcode 763划分字母区间
算法·leetcode·职场和发展
不会就选b8 小时前
算法日常・每日刷题--<动态规划>20
算法·leetcode·动态规划
别动我齐刘海9 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
青少儿编程课堂9 小时前
迪杰斯特拉(Dijkstra)算法:单源最短路与赛场路线规划
c++·python·算法·bfs·信息学竞赛
不会就选b9 小时前
算法日常・每日刷题--<动态规划>19
算法·leetcode·职场和发展
code2cat10 小时前
Java进阶篇之AtomicLongFieldUpdater:把累计额度留在对象字段中
java·cas·并发编程
WeiXin_DZbishe10 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计
泡茶喝茶写代码10 小时前
A股量化数据工程:从 REST 接口到策略信号(第 18 篇):放量缩量异动扫描
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口