引用计数法和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 相关文章推荐
解决SpringCloud Feign传对象参数调用失败的问题
Jun 23 Java/Android
分析Java中Map的遍历性能问题
Jun 26 Java/Android
详解Spring事件发布与监听机制
Jun 30 Java/Android
Java图书管理系统,课程设计必用(源码+文档)
Jun 30 Java/Android
SpringBoot读取Resource下文件的4种方法
Jul 02 Java/Android
SpringBoot实现quartz定时任务可视化管理功能
Aug 30 Java/Android
Java实现经典游戏泡泡堂的示例代码
Apr 04 Java/Android
Java8 Stream API 提供了一种高效且易于使用的处理数据的方式
Apr 13 Java/Android
Java存储没有重复元素的数组
Apr 29 Java/Android
Java线程的6种状态与生命周期
May 11 Java/Android
Android开发手册Chip监听及ChipGroup监听
Jun 10 Java/Android
Java实现注册登录跳转
Jun 16 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
《星际争霸重制版》兵种对比图鉴
2020/03/02 星际争霸
php实现Mongodb自定义方式生成自增ID的方法
2015/03/23 PHP
PHP数组相关函数汇总
2015/03/24 PHP
php文件操作相关类实例
2015/06/18 PHP
thinkPHP中分页用法实例分析
2015/12/26 PHP
Laravel5.5 视图 - 创建视图和数据传递示例
2019/10/21 PHP
JavaScript初学者应注意的七个细节详细介绍
2012/12/27 Javascript
js jquery验证银行卡号信息正则学习
2013/01/21 Javascript
Document:getElementsByName()使用方法及示例
2013/10/28 Javascript
javascript的propertyIsEnumerable()方法使用介绍
2014/04/09 Javascript
JavaScript的Date()方法使用详解
2015/06/09 Javascript
JavaScript中日期的相关操作方法总结
2015/10/24 Javascript
对javascript继承的理解
2016/10/11 Javascript
微信小程序 获取二维码实例详解
2017/06/23 Javascript
20行JS代码实现网页刮刮乐效果
2017/06/23 Javascript
js事件委托和事件代理案例分享
2017/07/25 Javascript
vue在使用ECharts时的异步更新和数据加载详解
2017/11/22 Javascript
vue中rem的配置的方法示例
2018/08/30 Javascript
vue+axios+promise实际开发用法详解
2018/10/15 Javascript
vue项目首屏加载时间优化实战
2019/04/23 Javascript
JS常见错误(Error)及处理方案详解
2020/07/02 Javascript
js屏蔽F12审查元素,禁止修改页面代码等实现代码
2020/10/02 Javascript
[28:28]Ti4 冒泡赛第二天NEWBEE vs NaVi 2
2014/07/15 DOTA
Python实现代码统计工具(终极篇)
2016/07/04 Python
Python 批量合并多个txt文件的实例讲解
2018/05/08 Python
python实现顺时针打印矩阵
2019/03/02 Python
Pytorch Tensor的统计属性实例讲解
2019/12/30 Python
Python StringIO及BytesIO包使用方法解析
2020/06/15 Python
Html5 页面适配iPhoneX(就是那么简单)
2019/09/05 HTML / CSS
Lookfantastic阿联酋官网:英国知名美妆护肤购物网站
2020/05/26 全球购物
公司担保书范文
2014/05/21 职场文书
个人简历自荐信
2014/06/26 职场文书
先进个人评语大全
2015/01/04 职场文书
python使用openpyxl库读写Excel表格的方法(增删改查操作)
2021/05/02 Python
比较几种Redis集群方案
2021/06/21 Redis
Django基础CBV装饰器和中间件
2022/03/22 Python