Java基础 -> GC如何判断对象可以被回收
2022/2/22 20:27:06
本文主要是介绍Java基础 -> GC如何判断对象可以被回收,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
GC如何判断对象可以被回收
-
引⽤计数法
(已被淘汰):每个对象有⼀个引⽤计数属性
,新增⼀个引⽤时计数加1,引⽤释放时计数减1,计数为0时可以回收
- 目前主流的java虚拟机
都摒弃
掉了这种算法,最主要的原因是它很难解决对象之间相互循环引用的问题。 - 尽管该算法执行效率很高。
- 目前主流的java虚拟机
-
可达性分析法
:从 GC Roots 开始向下搜索,搜索所⾛过的路径称为引⽤链。当⼀个对象到 GC Roots 没有任何引⽤链相连时,则证明此对象是不可⽤的,那么虚拟机就判断是可回收对象。- 目前主流的编程语言(java,C#等)的主流实现中,
都是通过可达性分析
来判定对象是否存活的。
- 目前主流的编程语言(java,C#等)的主流实现中,
对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象,等待垃圾回收。
GC Roots的对象有:
-
虚拟机栈中引⽤的对象 ->
堆中的对象与栈之间没有任何引用
-
⽅法区中类静态属性引⽤的对象 ->
堆中的对象与静态属性没有任何引用
-
⽅法区中常量引⽤的对象 ->
堆中的对象与常量没有任何引用
-
本地⽅法栈中Native⽅法引⽤的对象 ->
堆中的对象与本地⽅法栈没有任何引用
堆中的对象在四个地方都没有任何引用时,表示是可以被回收的
被GC判断为”垃圾”的对象一定会回收吗?
堆中的对象在四个地方都没有任何引用时,对象一定会被回收吗?
答:
即使在可达性分析算法中不可达的对象,也并非是“非死不可”
的。对象拥有一次⾃我拯救的机会。
对象被系统
宣告死亡
⾄少要经历两次标记过程:
-
第⼀次是经过可达性分析发现
没有与GC Roots相连接的引⽤链
- 表示可以被回收了,但是有一次⾃我拯救的机会
-
第⼆次是在由虚拟机⾃动建⽴的Finalizer队列中判断是否需要执⾏
finalize()
⽅法。finalize()
⽅法是Object类中的方法,作用就是用来对象被回收时可以被拯救用的。
public class Object { protected void finalize() throws Throwable { } }
- 当对象变成(GC Roots)不可达时,GC会判断该对象
是否覆盖(重写)了finalize⽅法
,若未覆盖,则直接将其回收。 - 否则,若对象未执⾏过finalize⽅法,将其放⼊F-Queue队列,由⼀低优先级线程执⾏该队列中对象的finalize⽅法。
- 这个方法只能被执行一次,只能有一次加入队列的机会,从队列出去就不会再被加入队列了
- 执⾏finalize⽅法完毕后,GC会
再次判断
该对象是否可达,若不可达,则进⾏回收 - 否则,对象“复活”
由于
finalize()⽅法运⾏代价⾼昂
,不确定性⼤,⽆法保证各个对象的调⽤顺序,不推荐⼤家使⽤,建议遗忘它。
public class TestMain { public static void main(String[] args) { Test test = new Test(); // 第一次调用垃圾回收 // 对象为null,第一次标记为可以被回收,但此次调用finalize()不会被真正回收 test = null; System.gc(); // 第二次调用垃圾回收 // 对象为null,第二次不能再加入队列也不能再执行finalize()了,被真正回收了 test = null; System.gc(); } } class Test { //GC Roots: 来自静态属性 public static Object object = null; @Override protected void finalize() throws Throwable { super.finalize(); //引用静态属性 object = this; } }
这篇关于Java基础 -> GC如何判断对象可以被回收的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?