当前位置: 首页 > 后端技术 > Java

面试必问:JVM是如何判断deadobject的?

时间:2023-04-02 01:08:30 Java

在JVM中,有两个非常重要的知识点,一个是JVM的内存布局(JVM运行时的数据区),一个是垃圾回收。垃圾回收有两个重要的知识点,一个是如何确定JVM中的垃圾对象,另一个是使用不同的垃圾回收器进行垃圾回收。本文将讨论前者,我们将在下一篇文章中讨论后者。判断垃圾对象常用的算法有两种:引用计数器算法和可达性分析算法。一、引用计数算法引用计数(ReferenceCounting)属于垃圾收集器的早期实现算法。指的是在创建对象的时候关联一个与之对应的计数器。对象使用时加1,反之销毁。小时-1。当这个计数器为0时,表示这个对象没有被使用,可以被垃圾收集器回收。引用计数算法的优缺点是显而易见的。优点是垃圾回收比较及时,实时性比较高。只要对象计数器为0,就可以直接进行回收操作;缺点是不能解决循环引用的问题,比如下面的代码:publicclassRefCounterTest{//ObjectAstaticclassRefObjectA{privateRefObjectBrefObjectB;publicvoidsetRefObjectB(RefObjectBrefObjectB){this.refObjectB=refObjectB;}}//对象B静态类RefObjectB{privateRefObjectArefObjectA;publicvoidsetRefObjectA(RefObjectArefObjectA){this.refObjectA=refObjectA;}}//测试代码publicstaticvoidmain(String[]args){RefObjectAobjectA=newRefObjectA();RefObjectBobjectB=newRefObjectB();objectA.setRefObjectB(objectB);objectB.setRefObjectA(objectA);对象A=空;对象B=空;}}如上代码所示,即使main方法中的objectA和objectB都设置为null,也就是根本没有使用到这两个对象,但是由于两者之间存在相互引用的关系,所以它们对应的对象计数器不为0,就会出现循环引用导致垃圾数据无法清除的情况。2.可达性分析算法可达性分析算法(ReachabilityAnalysis)是目前主流虚拟机中判断垃圾对象应用最广泛的实现算法。是指从对象的起点(GCRoots)向下查找,如果对象和GCRoots之间没有引用链接,也就是说,当对象到GCRoots不可达时,说明对象可以被垃圾回收器回收,如下图所示:在Java语言中,可以作为根节点(GCRoots)的对象有以下四种:Java虚拟机栈中的引用对象,即Java虚拟机栈帧中局部变量表中存储的(引用)对象。Java虚拟机栈帧中存放的对象是以后执行要用到的对象,所以与引用对象相关的对象是不能回收的;本地方法栈中的引用对象类似于Java虚拟机栈中的引用对象,不能被回收;方法区中类静态属性引用的对象也可以作为GCRoots;方法区常量引用的对象也可以作为GCRoots。因为常量存放在常量池中,是全局可用的对象,所以也可以作为GCRoots。3、关于“引用”,无论是引用计数法还是可达性分析算法都与对象的“引用”有关,可见对象的引用决定了对象的生死,Java中的引用也比较复杂。从JDK1.2开始,(引用)分为以下四种:强引用:代码中无处不在的引用,比如Objectobj=newObject(),只要强引用还在,垃圾回收器永远不会回收被引用的软引用:是一种相对弱于强引用的引用,可以使对象免于某些垃圾回收。只有当JVM认为内存不足时,才会尝试回收软引用指向的对象,JVM会确保在抛出OutOfMemoryError之前,清理掉软引用指向的对象;弱引用:非本质对象,但其强度弱于软引用,与弱引用关联的对象只能存活到下一次垃圾回收发生;virtualreference:也称为Ghostreference或phantomreference,是最弱的一种引用关系。不可能通过幻象引用获得一个对象实例。为一个对象设置虚引用只有一个目的,就是当一个对象被回收器回收时收到系统通知。.小结判断垃圾对象常用的算法有两种:引用计数器算法和可达性分析算法。其中,引用计数器算法实现简单,运行高效,但存在循环引用问题,因此主流虚拟机采用可达性分析算法。可达性分析算法从对象的根节点GCRoots开始向下搜索。如果根节点相连,则为普通对象,否则为垃圾对象,可被垃圾收集器回收。本文已收录在Gitee开源仓库《Java 面试指南》,其中包括:Redis、JVM、并发、并发、MySQL、Spring、SpringMVC、SpringBoot、SpringCloud、MyBatis、设计模式、消息队列等模块。Java面试就够了:超全Java常见面试题,持续更新中...