引用计数法和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并发编程之Executor接口的使用
Jun 21 Java/Android
总结一下关于在Java8中使用stream流踩过的一些坑
Jun 24 Java/Android
Java基础-封装和继承
Jul 02 Java/Android
swagger如何返回map字段注释
Jul 03 Java/Android
JavaWeb 入门篇(3)ServletContext 详解 具体应用
Jul 16 Java/Android
Log4j.properties配置及其使用
Aug 02 Java/Android
Java后台生成图片的完整步骤
Aug 04 Java/Android
Java 实战项目之家居购物商城系统详解流程
Nov 11 Java/Android
JavaScript正则表达式实现注册信息校验功能
May 30 Java/Android
ConditionalOnProperty配置swagger不生效问题及解决
Jun 14 Java/Android
Android学习之BottomSheetDialog组件的使用
Jun 21 Java/Android
向Spring IOC 容器动态注册bean实现方式
Jul 15 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去除字符串换行符示例分享
2014/02/13 PHP
PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
2016/09/11 PHP
PHP实现RTX发送消息提醒的实例代码
2017/01/03 PHP
jquery 页面滚动到指定DIV实现代码
2013/09/25 Javascript
自己动手实现jQuery Callbacks完整功能代码详解
2013/11/25 Javascript
javascript实现页面内关键词高亮显示代码
2014/04/03 Javascript
jQuery自动完成插件completer附源码下载
2016/01/04 Javascript
深入理解React中es6创建组件this的方法
2016/08/29 Javascript
JQuery遍历元素的后代和同胞实现方法
2016/09/18 Javascript
AngularJS2中一种button切换效果的实现方法(二)
2017/03/27 Javascript
Vue进度条progressbar组件功能
2018/04/17 Javascript
解决angular2在双向数据绑定时[(ngModel)]无法使用的问题
2018/09/13 Javascript
vue移动端实现手机左右滑动入场动画
2020/06/17 Javascript
微信小程序点击生成朋友圈分享图(遇到的坑)
2020/06/17 Javascript
如何手写一个简易的 Vuex
2020/10/10 Javascript
python使用scrapy解析js示例
2014/01/23 Python
Python获取电脑硬件信息及状态的实现方法
2014/08/29 Python
对变量赋值的理解--Pyton中让两个值互换的实现方法
2017/11/29 Python
Python爬虫框架scrapy实现downloader_middleware设置proxy代理功能示例
2018/08/04 Python
Python实现查找数组中任意第k大的数字算法示例
2019/01/23 Python
pycharm+PyQt5+python最新开发环境配置(踩坑)
2019/02/11 Python
pyqt 多窗口之间的相互调用方法
2019/06/19 Python
python opencv 二值化 计算白色像素点的实例
2019/07/03 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
2019/10/12 Python
Python基于time模块表示时间常用方法
2020/06/18 Python
使用before和:after伪类制作css3圆形按钮
2014/04/08 HTML / CSS
HTML5使用Audio标签实现歌词同步的效果
2016/03/17 HTML / CSS
彪马日本官网:PUMA日本
2019/01/31 全球购物
医学毕业生自荐信
2013/10/11 职场文书
劳动模范事迹材料
2014/01/19 职场文书
2014年幼儿园国庆主题活动方案
2014/09/16 职场文书
2014年党员自我评议总结
2014/09/23 职场文书
孟佩杰观后感
2015/06/17 职场文书
运动会主持词大全
2015/07/02 职场文书
MySQL窗口函数的具体使用
2021/11/17 MySQL
《异世界四重奏》剧场版6月10日上映 PV视觉图原创角色发表
2022/03/20 日漫