引用计数法和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 相关文章推荐
Spring整合Mybatis的全过程
Jun 28 Java/Android
Java异常处理try catch的基本用法
Dec 06 Java/Android
mybatis源码解读之executor包语句处理功能
Feb 15 Java/Android
Java实现二分搜索树的示例代码
Mar 17 Java/Android
Spring事务管理下synchronized锁失效问题的解决方法
Mar 31 Java/Android
Android超详细讲解组件ScrollView的使用
Mar 31 Java/Android
Java 垃圾回收超详细讲解记忆集和卡表
Apr 08 Java/Android
JAVA 线程池(池化技术)的实现原理
Apr 28 Java/Android
Java对文件的读写操作方法
Apr 29 Java/Android
Java实现扫雷游戏详细代码讲解
May 25 Java/Android
java.util.NoSuchElementException原因及两种解决方法
Jun 28 Java/Android
HttpClient实现表单提交上传文件
Aug 14 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
用PHP制作静态网站的模板框架(四)
2006/10/09 PHP
约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
2010/10/12 PHP
探讨:使用XMLSerialize 序列化与反序列化
2013/06/08 PHP
destoon实现商铺管理主页设置增加新菜单的方法
2014/06/26 PHP
mac系统下安装多个php并自由切换的方法详解
2017/04/21 PHP
显示js对象所有属性和方法的函数
2009/10/16 Javascript
Jquery Ajax学习实例5 向WebService发出请求,返回泛型集合数据的异步调用
2010/03/17 Javascript
从零开始学习jQuery (十) jQueryUI常用功能实战
2011/02/23 Javascript
js 中的switch表达式使用示例
2020/06/03 Javascript
Jquery模仿Baidu、Google搜索时自动补充搜索结果提示
2013/12/26 Javascript
一个JavaScript处理textarea中的字符成每一行实例
2014/09/22 Javascript
JSONP跨域GET请求解决Ajax跨域访问问题
2014/12/31 Javascript
AngularJS数据源的多种获取方式汇总
2016/02/02 Javascript
浅谈JavaScript的内置对象和浏览器对象
2016/06/03 Javascript
BootStrap轮播HTML代码(推荐)
2016/12/10 Javascript
javascript中setAttribute兼容性用法分析
2016/12/12 Javascript
扩展bootstrap的modal模态框-动态添加modal框-弹出多个modal框
2017/02/21 Javascript
Vue组件间通信 Vuex的用法解析
2019/08/05 Javascript
使用localStorage替代cookie做本地存储
2019/09/25 Javascript
解决Vue 给mapState中定义的属性赋值报错的问题
2020/06/22 Javascript
微信小程序中data-key属性之数据传输(经验总结)
2020/08/22 Javascript
vue 公共列表选择组件,引用Vant-UI的样式方式
2020/11/02 Javascript
[02:28]DOTA2亚洲邀请赛 LGD战队巡礼
2015/02/03 DOTA
[02:21]十步杀一人,千里不留行——DOTA2全新英雄天涯墨客展示
2018/08/29 DOTA
python实现逆波兰计算表达式实例详解
2015/05/06 Python
使用Python给头像加上圣诞帽或圣诞老人小图标附源码
2019/12/25 Python
Python+PyQt5+MySQL实现天气管理系统
2020/06/16 Python
Python使用windows设置定时执行脚本
2020/11/12 Python
深入解析HTML5使用SVG图像时的viewBox属性用法
2015/09/02 HTML / CSS
广告学专业求职信
2014/06/19 职场文书
实习证明格式范文
2014/10/14 职场文书
司法局2014法制宣传日活动总结
2014/11/01 职场文书
会议欢迎词范文
2015/01/27 职场文书
2015年学校工作总结范文
2015/04/20 职场文书
写给媳妇的检讨书
2015/05/06 职场文书
使用Python的开发框架Brownie部署以太坊智能合约
2021/05/28 Python