引用计数法和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 Swing实现自助取款机系统
Jun 11 Java/Android
Java并发编程之详解CyclicBarrier线程同步
Jun 23 Java/Android
IDEA使用SpringAssistant插件创建SpringCloud项目
Jun 23 Java/Android
SpringBoot实现异步事件驱动的方法
Jun 28 Java/Android
Springboot集成阿里云OSS上传文件系统教程
Jun 28 Java/Android
logback如何自定义日志存储
Aug 30 Java/Android
Spring-cloud Config Server的3种配置方式
Sep 25 Java/Android
Java 写一个简单的图书管理系统
Apr 26 Java/Android
Java中Dijkstra(迪杰斯特拉)算法
May 20 Java/Android
openGauss数据库JDBC环境连接配置的详细过程(Eclipse)
Jun 01 Java/Android
解决spring.thymeleaf.cache=false不起作用的问题
Jun 10 Java/Android
java获取一个文本文件的编码(格式)信息
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开启gzip页面压缩实例
2013/06/09 PHP
php第一次无法获取cookie问题处理
2014/12/15 PHP
PHP中substr函数字符串截取用法分析
2016/01/07 PHP
thinkphp制作404跳转页的简单实现方法
2016/09/22 PHP
获取Javscript执行函数名称的方法
2006/12/22 Javascript
jQuery 源码分析笔记(2) 变量列表
2011/05/28 Javascript
推荐40款强大的 jQuery 导航插件和教程(上篇)
2012/09/14 Javascript
event.currentTarget与event.target的区别介绍
2012/12/31 Javascript
javascript firefox 自动加载iframe 自动调整高宽示例
2013/08/27 Javascript
jquery实现动态菜单的实例代码
2013/11/28 Javascript
javascript简单实现图片预加载
2014/12/03 Javascript
基于jquery实现鼠标滚轮驱动的图片切换效果
2015/10/26 Javascript
JavaScript电子时钟倒计时
2016/01/09 Javascript
CSS3 3D 技术手把手教你玩转
2016/09/02 Javascript
JavaScript获取服务器时间的方法详解
2016/12/11 Javascript
滚动条的监听与内容随着滚动条动态加载的实现
2017/02/08 Javascript
Nodejs之TCP服务端与客户端聊天程序详解
2017/07/07 NodeJs
通过javascript实现段落的收缩与展开
2019/06/26 Javascript
通过GASP让vue实现动态效果实例代码详解
2019/11/24 Javascript
详解小程序BackgroundAudioManager踩坑之旅
2019/12/08 Javascript
[01:18:31]DOTA2-DPC中国联赛定级赛 LBZS vs Magma BO3第一场 1月10日
2021/03/11 DOTA
Python中实现三目运算的方法
2015/06/21 Python
Python Web框架Tornado运行和部署
2020/10/19 Python
python matplotlib画图实例代码分享
2017/12/27 Python
Python查找第n个子串的技巧分享
2018/06/27 Python
tensorflow实现图像的裁剪和填充方法
2018/07/27 Python
django从请求到响应的过程深入讲解
2018/08/01 Python
PyCharm GUI界面开发和exe文件生成的实现
2020/03/04 Python
django教程如何自学
2020/07/31 Python
What's the difference between Debug and Trace class? (Debug类与Trace类有什么区别)
2013/09/10 面试题
建筑文秘专业个人求职信范文
2013/12/28 职场文书
给老师的一封建议书
2014/03/13 职场文书
2015年商场工作总结
2015/04/27 职场文书
刑事附带民事诉讼答辩状
2015/05/22 职场文书
《月光曲》教学反思
2016/02/16 职场文书
2019年国庆祝福语(70句)
2019/09/19 职场文书