引用计数法和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 相关文章推荐
使用feign服务调用添加Header参数
Jun 23 Java/Android
SpringBoot 拦截器妙用你真的了解吗
Jul 01 Java/Android
Spring Cloud Gateway去掉url前缀
Jul 15 Java/Android
关于springboot 配置date字段返回时间戳的问题
Jul 25 Java/Android
Java Spring 控制反转(IOC)容器详解
Oct 05 Java/Android
OpenCV实现普通阈值
Nov 17 Java/Android
OpenCV实现反阈值二值化
Nov 17 Java/Android
Java 数据结构七大排序使用分析
Apr 02 Java/Android
Java 超详细讲解hashCode方法
Apr 07 Java/Android
Spring Data JPA框架Repository自定义实现
Apr 28 Java/Android
Java+swing实现抖音上的表白程序详解
Jun 25 Java/Android
IDEA中sout快捷键无效问题的解决方法
Jul 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
各种咖啡的英文名子是什么
2021/03/03 新手入门
PHP4引用文件语句的对比
2006/10/09 PHP
php检测用户是否用手机(Mobile)访问网站的类
2014/01/09 PHP
浅谈php命令行用法
2015/02/04 PHP
Symfony2在Nginx下的配置方法图文教程
2016/02/04 PHP
PHP控制前台弹出对话框的实现方法
2016/08/21 PHP
基于laravel-admin 后台 列表标签背景的使用方法
2019/10/03 PHP
建立良好体验度的Web注册系统ajax
2007/07/09 Javascript
js关于精确计算和数值格式化以及直接引js文件
2014/01/28 Javascript
学习javascript面向对象 掌握创建对象的9种方式
2016/01/04 Javascript
Jquery遍历select option和添加移除option的实现方法
2016/08/26 Javascript
vue实现可增删查改的成绩单
2016/10/27 Javascript
简单谈谈require模块化jquery和angular的问题
2017/06/23 jQuery
Vue.js中extend选项和delimiters选项的比较
2017/07/17 Javascript
微信小程序实现简易table表格
2020/06/19 Javascript
微信二次分享报错invalid signature问题及解决方法
2019/04/01 Javascript
JS实现滚动条触底加载更多
2019/09/19 Javascript
通过实例了解JS 连续赋值
2019/09/24 Javascript
Vue 实现一个命令式弹窗组件功能
2019/09/25 Javascript
在微信小程序中渲染HTML内容3种解决方案及分析与问题解决
2020/01/12 Javascript
用pywin32实现windows模拟鼠标及键盘动作
2014/04/22 Python
使用IPython来操作Docker容器的入门指引
2015/04/08 Python
python验证码识别的实例详解
2016/09/09 Python
【Python】Python的urllib模块、urllib2模块批量进行网页下载文件
2016/11/19 Python
python使用pip安装SciPy、SymPy、matplotlib教程
2019/11/20 Python
在pytorch 中计算精度、回归率、F1 score等指标的实例
2020/01/18 Python
python2.7使用scapy发送syn实例
2020/05/05 Python
Python基于wordcloud及jieba实现中国地图词云图
2020/06/09 Python
Python中生成ndarray实例讲解
2021/02/22 Python
骨干教师培训感言
2014/01/16 职场文书
个人现实表现材料
2014/02/04 职场文书
公司节能减排倡议书
2014/05/14 职场文书
应届大专生自荐书
2014/06/16 职场文书
化学专业大学生职业生涯规划范文
2014/09/13 职场文书
2015共产党员公开承诺书
2015/01/22 职场文书
Mysql MVCC机制原理详解
2021/04/20 MySQL