如何判断对象是否已死?

文章来源
前言
程序开发过程中,我们频繁的与对象打交道,不断的创建对象,我们知道如何使用与协调对象来实现我们的意图,但是我们常常不关心对象的死活。
对象也有自己的生命周期,有诞生的时候,也就有消亡的时候。创建对象时,我们会有引用指向这个对象,为了可以访问到这个对象。
那没有引用指向对象的时候,就代表对象死亡了吗?其实不然,判断对象是否死亡是Java虚拟机的工作,使用的是可达性分析算法进行判断的,当对象被判断为死亡时,很快就会被GC清理回收。

一、引用的种类

可达性分析算法是判断对象是否死亡的算法,但是在介绍其之前,我们先来看看引用的种类。我们创建对象时,常常会有引用指向这个对象,引用就是一个地址,类似C语言中的指针,通过这个地址可访问到某个对象,在Java中对象几乎全部存放在堆内存中,而引用大部分存储于栈的本地变量表中。
在Java中,引用的种类分为四种,分别是:强引用、软引用、弱引用以及虚引用。
强引用(Strong Reference):强引用是我们开发使用最多的,如Object obj = new Object();obj这个引用就是强引用,只要obj引用还存在,其指向的对象就不会被GC回收。
软引用(Soft Reference):使用java.lang.ref包下的SoftReference类可以实现软引用,软引用指向的对象一般是有用但又不是必须的,在内存溢出之前,GC会回收这些软引用所指向的对象。
弱引用(Weak Reference):使用java.lang.ref包下的WeakReference类可以实现弱引用,弱引指向的对象不是必须的,引用关系比软引用弱一点,在下一次GC的时候,就会回收这些弱引用指向的对象。
虚引用(Phantom Reference):使用java.lang.ref包下的PhantomReference类可以实现虚引用,虚引用也被成为幻影引用,一个不会影响对象生命周期的引用,非常弱,使用其仅仅是为了在对象被回收时收到一个死亡通知。解释一下,下一次GC的意思就是下一次发生Minor GC或Major GC的时候,Minor GC主要回收堆中的新生代内存,Major GC会回收堆中老年代的内存,但Major GC发生时常常会发生一次Minor GC,这些是垃圾回收范畴的知识了。

二、引用计数算法

引用计数算法虽然不是Java虚拟机判断对象是否存活的算法,但是却有很多语言使用这种算法进行管理内存,如流行得不要不要的Python,所以还是有必须要了解一下。
引用计数算法原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器就加1;当引用失效时,计数器就减1;任何时刻计数器为0的对象就是不可能被使用的,也就是被视为死亡的。
引用计数器算法简单高效,但是解决不了循环引用的问题。而循环引用在Java中是十分常见的现象,如A对象的某个属性引用了B对象,而B对象的某个属性引用了A对象,而其他地方并没有引用这两个对象,如果使用引用计数算法,则这两个对象都不会被视为死亡的,也就不会被GC回收。
三、可达性分析算法

在Java、C#等语言中都是通过可达性分析算法来判定对象是否存活的。
可达性分析算法原理:通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。
在Java语言中,可作为GC Roots的对象包括下面几种:
1、虚拟机栈(栈帧中的本地变量表)中引用的对象。程序运行在调用方法时会创建一个栈帧,方法中使用到的变量会被记录在本地变量表中。
2、方法区中类静态属性引用的对象。类中static修饰的变量。
3、方法区中常量引用的对象。类中static final修饰的变量。
4、本地方法栈中JNI(一般来说是Native方法)引用的对象。如String类中的本地方法intern()引用的字符串对象。
四、总结
简单总结一下,本文主要介绍了四种引用类型,即强引用、软引用、弱引用以及虚引用,两个判断对象是否存活的算法,即引用计数算法和可达性发现算法,Java虚拟机使用的是后者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值