JVM中如何判断一个对象是否为可回收

JVM在进行垃圾回收之前,必然要做的就是判断哪些对象可以回收,哪些对象不可以回收,要进行这样的划分一般有两种方式,一种为引用链计数法,一种为可达性分析法。

引用计数法

这是一种非常简单的方法,为每一个对象中添加一个计数器,当对象被引用时,计数器就加1,当引用被释放时,计数器就减1,最后如果计数器为0,则表示该对象没有任何引用关系了,即为垃圾对象。

这是一种实现简单,判定效率较高的方法,也有一些著名的应用案例,比如Python语言中就使用了这种方式,但是在JVM中并没有使用这种算法,因为它存在一个明显的问题:循环引用。

如下图所示,A引用B,B引用A,除此之外再无其他任何对象引用了这个两个对象,所以这两个对象应当为垃圾对象,但却因为计数器都不为0,所以不能被回收。
在这里插入图片描述

可达性分析法

为了避免上述的问题,在JVM中采用的是另一种可达性分析法来判断对象是否存活,这个算法的思想就是通过判断一系列被称为GCRoots的根对象,并作为起点,根据引用关系向下查找,查找过的路径称为引用链,如果某个对象到GCRoots对象没有任何一条引用链,则判断此对象为可回收对象。

如下图所示,D、G对象与GCRoots没有任何引用链关系所以为可回收对象。
在这里插入图片描述
在Java技术体系里面,固定可作为GC Roots的对象包括以下几种:

1、在虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆栈中使用到的 参数、局部变量、临时变量等。

2、在方法区中类静态属性引用的对象,譬如Java类的引用类型静态变量。

3、在方法区中常量引用的对象,譬如字符串常量池(String Table)里的引用。

4、在本地方法栈中JNI(即通常所说的Native方法)引用的对象。

5、Java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻的异常对象(比如 NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。

6、所有被同步锁(synchronized关键字)持有的对象。

7、反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。

除此之外根据某些垃圾收集器的选用,还有可能会存在临时性的GCRoot对象,因为垃圾划代收集的方式,比如扫描新生代对象的时候,还需要考虑被老年代中对象引用的情况,此时老年代中的对象也可视为GCRoot对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码拉松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值