垃圾回收标记阶段算法

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()方法不会在被调用(只会调用一次),对象直接会变为不可触及的状态。

相关推荐
边境悍匪12 分钟前
蜗牛学苑 Java 智能体学习 Day39|SpringAI 会话存储、Function‑Call 工具调用、MCP 思维导图复盘
java·开发语言·spring boot·学习·阿里云
302wanger18 分钟前
分享一个工作习惯:整点看即时消息
算法
letisgo539 分钟前
JAVA 高级进阶02篇《并发编程三板斧:JMM、CAS与AQS的源码级拆解》
java·面试·并发编程·aqs·jmm
胡写代码44 分钟前
若依 + MyBatis-Plus,分页为什么悄悄失效了?
java·后端
yxlalm1 小时前
4.java秒杀项目第四课-后端商品后台接口
java·开发语言
宁之明起(B服)1 小时前
vulhub靶场(tomcat三件套:PUT写马、Ghostcat与manager弱口令)
java·tomcat
君顾11 小时前
家政派单小程序源码开发实战:从零搭建到上线全流程指南
java·开发语言·家政派单
流烟默1 小时前
HTTP 连接管理技术梳理:JDK KeepAliveCache 机制与池化选型
java·网络协议·http
阿酷tony2 小时前
视频专栏列表的防录屏水印和跑马灯效果(也可网站调用)
java·前端·音视频
洋不写bug2 小时前
排序(一)基础排序,插入|希尔|冒泡|直接选择排序详解
java·算法·排序算法·插入排序·冒泡排序·希尔排序·直接选择排序