引用计数法和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中一些比较常用的注解总结
Jun 11 Java/Android
gateway与spring-boot-starter-web冲突问题的解决
Jul 16 Java/Android
Sleuth+logback 设置traceid 及自定义信息方式
Jul 26 Java/Android
解析mybatis-plus中的resultMap简单使用
Nov 23 Java/Android
Spring依赖注入多种类型数据的示例代码
Mar 31 Java/Android
Android自定义双向滑动控件
Apr 19 Java/Android
Spring Boot配合PageHelper优化大表查询数据分页
Apr 20 Java/Android
springboot读取nacos配置文件
May 20 Java/Android
spring IOC容器的Bean管理XML自动装配过程
May 30 Java/Android
SpringBoot使用AOP实现统计全局接口访问次数详解
Jun 16 Java/Android
Java中的Kafka为什么性能这么快及4大核心详析
Sep 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
php使用Smarty的相关注意事项及访问变量的几种方式
2011/12/08 PHP
THINKPHP2.0到3.0有哪些改进之处
2015/01/04 PHP
PHP-X系列教程之内置函数的使用示例
2017/10/16 PHP
php数值计算num类简单操作示例
2020/05/15 PHP
用javascript动态调整iframe高度的代码
2007/04/10 Javascript
Javascript 更新 JavaScript 数组的 uniq 方法
2008/01/23 Javascript
原生JS可拖动弹窗效果实例代码
2013/11/09 Javascript
jquery实现点击消失的代码
2014/03/03 Javascript
浅谈javascript面向对象程序设计
2015/01/21 Javascript
jQuery实现contains方法不区分大小写的方法
2015/02/13 Javascript
JavaScript奇技淫巧44招【实用】
2016/12/11 Javascript
vue中将网页打印成pdf实例代码
2017/06/15 Javascript
获取当前按钮或者html的ID名称实例(推荐)
2017/06/23 Javascript
JavaScript比较同一天的时间大小实例代码
2018/02/09 Javascript
不使用JavaScript实现菜单的打开和关闭效果demo
2018/05/01 Javascript
小程序tab页无法传递参数的方法
2018/08/03 Javascript
学习使用ExpressJS 4.0中的新Router的用法
2018/11/06 Javascript
详解javascript中的Error对象
2019/04/25 Javascript
JS实现获取当前所在周的周六、周日示例分析
2019/05/11 Javascript
bootstrap Table实现合并相同行
2019/07/19 Javascript
Vue列表循环从指定下标开始的多种解决方案
2020/04/08 Javascript
[45:50]完美世界DOTA2联赛PWL S3 CPG vs Forest 第二场 12.16
2020/12/17 DOTA
Python实现上下班抢个顺风单脚本
2018/02/07 Python
解析python实现Lasso回归
2019/09/11 Python
python wxpython 实现界面跳转功能
2019/12/17 Python
VSCode配合pipenv搞定虚拟环境的实现方法
2020/05/17 Python
python + selenium 刷B站播放量的实例代码
2020/06/12 Python
Python fileinput模块如何逐行读取多个文件
2020/10/05 Python
html5组织内容_动力节点Java学院整理
2017/07/10 HTML / CSS
Myprotein西班牙官网:欧洲第一大运动营养品牌
2020/02/24 全球购物
读群众路线心得体会
2014/03/07 职场文书
大学生创业项目方案
2014/03/08 职场文书
食品安全汇报材料
2014/08/18 职场文书
教师批评与自我批评材料
2014/10/16 职场文书
发工资啦!教你用Python实现邮箱自动群发工资条
2021/05/10 Python
Windows Server 2012 R2服务器安装与配置的完整步骤
2022/07/15 Servers