引用计数法和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 相关文章推荐
Springboot如何使用logback实现多环境配置?
Jun 16 Java/Android
Java新手教程之ArrayList的基本使用
Jun 20 Java/Android
springBoot基于webSocket实现扫码登录
Jun 22 Java/Android
Java多条件判断场景中规则执行器的设计
Jun 26 Java/Android
Springboot使用Spring Data JPA实现数据库操作
Jun 30 Java/Android
Java获取e.printStackTrace()打印的信息方式
Aug 07 Java/Android
spring cloud eureka 服务启动失败的原因分析及解决方法
Mar 17 Java/Android
RestTemplate如何通过HTTP Basic Auth认证示例说明
Mar 17 Java/Android
java如何实现获取客户端ip地址的示例代码
Apr 07 Java/Android
Java 写一个简单的图书管理系统
Apr 26 Java/Android
Spring IOC容器Bean的作用域及生命周期实例
May 30 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
PHP关联链接常用代码
2012/11/05 PHP
php使用APC实现实时上传进度条功能
2015/10/26 PHP
关于扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题分析
2016/01/08 PHP
YII Framework教程之异常处理详解
2016/03/14 PHP
如何使用php等比例缩放图片
2016/10/12 PHP
PHP单例模式与工厂模式详解
2017/08/29 PHP
PHP判断函数是否被定义的方法
2019/06/21 PHP
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
2007/05/03 Javascript
JS维吉尼亚密码算法实现代码
2010/11/09 Javascript
深入解析JavaScript中的变量作用域
2013/12/06 Javascript
JavaScript实现的石头剪刀布游戏源码分享
2014/08/22 Javascript
jQuery中change事件用法实例
2014/12/26 Javascript
javascript实现PC网页里的拖拽效果
2016/03/14 Javascript
vue.js实现表格合并示例代码
2016/11/30 Javascript
详解node字体压缩插件font-spider的用法
2018/09/28 Javascript
vue 移动端适配方案详解
2018/11/15 Javascript
angular 用Observable实现异步调用的方法
2018/12/27 Javascript
webpack4.x下babel的安装、配置及使用详解
2019/03/07 Javascript
JS获取本地地址及天气的方法实例小结
2019/05/10 Javascript
JS中使用react-tooltip插件实现鼠标悬浮显示框
2019/05/15 Javascript
详解Vue中的基本语法和常用指令
2019/07/23 Javascript
JavaScript Array对象基本方法详解
2019/09/03 Javascript
基于js实现复制内容到操作系统粘贴板过程解析
2019/10/11 Javascript
webpack中的模式(mode)使用详解
2020/02/20 Javascript
微信小程序实现倒计时功能
2020/11/19 Javascript
[04:29]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/02/01 DOTA
python算法表示概念扫盲教程
2017/04/13 Python
Python内置函数 next的具体使用方法
2017/11/24 Python
django 实现将本地图片存入数据库,并能显示在web上的示例
2019/08/07 Python
Python SSL证书验证问题解决方案
2020/01/13 Python
python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)
2020/03/12 Python
一文带你了解Python 四种常见基础爬虫方法介绍
2020/12/04 Python
北京银河万佳Java面试题
2012/03/21 面试题
高三自我鉴定范文
2013/10/19 职场文书
mysql对于模糊查询like的一些汇总
2021/05/09 MySQL
Win11自动黑屏怎么办 Win11自动黑屏设置教程
2022/07/15 数码科技