怎么知道对象是否“没用”

对象是否死了

Java堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”(没用引用)了。关于怎么知道对象是否可用在Java世界中有两种!

引用计数

所谓引用计数就是指在new Object()的时候,在对象中存放个计数值,有引用指向就加一,当引用消失是就减一,直到零就可以回收了。但是在现在主流的虚拟机实现中却很少用到引用计数,因为引用计数需要配合好,搞不好还会内存泄漏,比如对象之间的循环引用问题。
举个栗子:两个对象A、B,里面有一个object的属性,A.object=B,B.object等于A,然后这两个对象就再无任何引用,外界也没法通过什么访问到,而且引用计数还不为零,无法进行回收。

package com.yedi.object;

/**
 * @author MILELU
 * @date 2020/10/26 9:24
 */
public class ReferenceCount {

    Object object=null;

    public static void main(String[] args) {

        ReferenceCount a = new ReferenceCount();

        ReferenceCount b = new ReferenceCount();

        a.object=b;

        b.object=a;
        a=null;
        b=null;
        System.gc();

    }

}
GC日志:
[GC (System.gc()) [PSYoungGen: 530K->504K(1024K)] 746K->728K(1536K), 0.0007884 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 504K->420K(1024K)] [ParOldGen: 224K->171K(512K)] 728K->591K(1536K), [Metaspace: 3109K->3109K(1056768K)], 0.0050099 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 

可以看到FUll GC里的YongGen从504->420,OdeGen:224k->171K,说明上面的代码还是被回收掉了,可以证明hotSopt不是使用引用计数来判断对象是否存活,因为引用计数这一段代码不会被回收。

可达性分析算法

Java是通过可达性分析算法来判断对象是否存活,而且同时解决了引用计数的缺点循环依赖问题。可达性分析就是通过一个GC Roots根对象作为节点一直连这一条线往下找,有引用的对象就会连着一条引用链,如果某个对象没有引用链相连的话就没法通过GC Roots找到它,就可以知道这个对象是没用的。

在这里插入图片描述
在Java技术体系里面,固定可作为GC Roots的对象包括以下几种:

  • 在虚拟机栈(栈帧中的本地变量表)中引用的对象,比如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。
  • 在方法区中类静态属性引用的对象,比如Java类的引用类型静态变量。
  • 在方法区中常量引用的对象,比如字符串常量池(String Table)里的引用。
  • 在本地方法栈中JNI(即通常所说的Native方法)引用的对象。
  • Java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻的异常对象(比如NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。
  • 所有被同步锁(synchronized关键字)持有的对象。
  • 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

搞数学的小混混

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

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

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

打赏作者

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

抵扣说明:

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

余额充值