引用计数法和root搜索算法以及JVM中判定对象需要回收的方法


Posted in Java/Android onApril 19, 2022

引用计数法

每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收

这个可以用数据算法中的图形表示,对象A-对象B-对象C 都有引用,所以不会被回收,对象B由于没有被引用,没有路径可以达到对象B,对象B的引用计数就就是0,对象B就会被回收。

引用计数法和root搜索算法以及JVM中判定对象需要回收的方法

但是这个算法有明显的缺陷,对于循环引用的情况下,循环引用的对象就不会被回收。例如下图:对象A,对象B 循环引用,没有其他的对象引用A和B,则A和B 都不会被回收。

引用计数法和root搜索算法以及JVM中判定对象需要回收的方法

root搜索算法

这种算法目前定义了几个root,也就是这几个对象是jvm虚拟机不会被回收的对象,所以这些对象引用的对象都是在使用中的对象,这些对象未使用的对象就是即将要被回收的对象。简单就是说:如果对象能够达到root,就不会被回收,如果对象不能够达到root,就会被回收。

引用计数法和root搜索算法以及JVM中判定对象需要回收的方法

被启动类(bootstrap加载器)加载的类和创建的对象
jvm运行时方法区类静态变量(static)引用的对象
jvm运行时方法去常量池引用的对象
jvm当前运行线程中的虚拟机栈变量表引用的对象
本地方法栈中(jni)引用的对象

引用计数法和root搜索算法以及JVM中判定对象需要回收的方法

jvm在确定是否回收的对象的时候采用的是root搜索算法来实现。

补充:jvm判断对象的回收

可达性分析算法

可达性分析算法:通过一系列“GC Roots”的根对象作为起始节点集,根据引用关系向下搜索,若某个对象到根对象无任何引用链相连,则此对象不可达。

但是可达性分析后为不可达的对象不是一定要回收,会经历一个二次标记过程。

二次标记

1.如果对象在可达性分析后结果为不可达,则会被第一次标记。接着进行筛选,筛选条件为是否执行finalize()方法。

  • 若该对象未覆盖finalize()方法,或finalize()已被调用过一次,则不需要执行finalize()方法。那么此对象判定为需要回收。

(对象的 finalize()方法只会被系统调用一次,下次回收该对象时, finalize()不会再执行)

  • 若该对象覆盖了finalize()方法,且finalize()方法未被调用过,则需要执行finalize()方法。

2.若该对象需要执行finalize()方法,则该对象会被放置在一个F-Queue的队列中,再由一个finalizer线程执行这些对象的finalize()方法。

3.接着收集器会堆F-Queue队列的对象进行二次标记,若对象在finalize() 方法中未能逃脱,那么该对象会被二次标记,二次标记的对象判定为需要回收;

(对象可以在 finalize()方法中,将自己和引用链上的对象建立引用关系,这样在第二次标记时,收集器会将其移出回收对象的集合,以此达到逃脱)

到此这篇关于jvm中如何判定对象需要回收的文章就介绍到这了!

Java/Android 相关文章推荐
一篇文章带你复习java知识点
Jun 28 Java/Android
Spring中bean的生命周期之getSingleton方法
Jun 30 Java/Android
关于springboot 配置date字段返回时间戳的问题
Jul 25 Java/Android
剑指Offer之Java算法习题精讲二叉树的构造和遍历
Mar 21 Java/Android
Java字符串逆序方法详情
Mar 21 Java/Android
详细介绍Java中的CyclicBarrier
Apr 13 Java/Android
Android使用EventBus发送消息,Fragment中接收消息的方法会执行多次
Apr 24 Java/Android
Jmerte 分布式压测及分布式压测配置
Apr 30 Java/Android
Java 数组的使用
May 11 Java/Android
java.util.NoSuchElementException原因及两种解决方法
Jun 28 Java/Android
Spring中bean集合注入的方法详解
Jul 07 Java/Android
Java中的Kafka为什么性能这么快及4大核心详析
Sep 23 Java/Android
解决springboot druid数据库连接失败后一直重连的方法
Apr 19 #Java/Android
Android自定义双向滑动控件
Apr 19 #Java/Android
java高级用法JNA强大的Memory和Pointer
Apr 19 #Java/Android
Java后端 Dubbo retries 超时重试机制的解决方案
Apr 14 #Java/Android
Java数组详细介绍及相关工具类
Apr 14 #Java/Android
Java8利用Stream对列表进行去除重复的方法详解
Apr 14 #Java/Android
详解Flutter网络请求Dio库的使用及封装
Apr 14 #Java/Android
You might like
探讨GDFONTPATH能否被winxp下的php支持
2013/06/21 PHP
PHP定时更新程序设计思路分享
2014/06/10 PHP
PHP嵌套输出缓冲代码实例
2015/05/12 PHP
两款万能的php分页类
2015/11/12 PHP
2017年最新PHP经典面试题目汇总(上篇)
2017/03/17 PHP
jQuery的三种$()
2009/12/30 Javascript
深入理解javascript动态插入技术
2013/11/12 Javascript
jQuery - css() 方法示例详解
2014/01/16 Javascript
JavaScript实现打字效果的方法
2015/07/10 Javascript
jquery实现简单的二级导航下拉菜单效果
2015/09/07 Javascript
Sea.JS知识总结
2016/05/05 Javascript
JavaScript实现时间倒计时跳转(推荐)
2016/06/28 Javascript
JavaScript中有关一个数组中最大值和最小值及它们的下表的输出的解决办法
2016/07/01 Javascript
jquery做个日期选择适用于手机端示例
2017/01/10 Javascript
JavaScript实现前端分页控件
2017/04/19 Javascript
vue移动端裁剪图片结合插件Cropper的使用实例代码
2017/07/10 Javascript
jquery如何实现点击空白处隐藏元素
2017/12/05 jQuery
Vue.js结合bootstrap前端实现分页和排序效果
2018/12/29 Javascript
Node.js之删除文件夹(含递归删除)代码实例
2019/09/09 Javascript
在Vue mounted方法中使用data变量详解
2019/11/05 Javascript
在Vuex中Mutations修改状态操作
2020/07/24 Javascript
Vue3为什么这么快
2020/09/23 Javascript
Python实现字典的key和values的交换
2015/08/04 Python
Python实现pdf文档转txt的方法示例
2018/01/19 Python
Python Numpy 数组的初始化和基本操作
2018/03/13 Python
分析运行中的 Python 进程详细解析
2019/06/22 Python
使用python-pptx包批量修改ppt格式的实现
2020/02/14 Python
python实例化对象的具体方法
2020/06/17 Python
在pycharm中文件取消用 pytest模式打开的操作
2020/09/01 Python
python3中确保枚举值代码分析
2020/12/02 Python
CSS实现圆形放大镜狙击镜效果 只有圆圈里的放大
2012/12/10 HTML / CSS
h5移动端调用支付宝、微信支付的实现
2020/06/08 HTML / CSS
送给程序员的20个Java集合面试问题
2014/08/06 面试题
市场营销专业应届生自荐信
2014/06/19 职场文书
2014年纠风工作总结
2014/12/08 职场文书
《中华上下五千年》读后感3篇
2019/11/29 职场文书