垃圾回收标记阶段算法

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

相关推荐
qqxhb3 分钟前
零基础设计模式——行为型模式 - 中介者模式
java·设计模式·go·中介者模式
forestsea12 分钟前
Maven 多仓库治理与发布策略深度实践
java·maven
陌殇殇21 分钟前
Hadoop 003 — JAVA操作MapReduce入门案例
java·hadoop·mapreduce
march of Time24 分钟前
图数据库介绍及应用,go和Java使用图数据库
java·数据库·golang
CodeCraft Studio26 分钟前
PDF处理控件Aspose.PDF教程: 在 Java 中编辑 PDF 页面大小
java·pdf·aspose·aspose.pdf
异常君27 分钟前
Redis String 类型的底层实现与性能优化
java·redis·性能优化
西京刀客30 分钟前
Go语言json.Marshal多态机制
算法·golang·json
白总Server30 分钟前
Golang实现分布式Masscan任务调度系统
java·运维·服务器·开发语言·分布式·后端·golang
A22741 小时前
自定义线程池 4.0
java·线程池
康小庄1 小时前
AQS独占模式——资源获取和释放源码分析
java·开发语言·jvm·spring boot·spring·spring cloud·nio