jvm如何判断对象是否可以被回收

内容基本来自周志明 深入理解Java虚拟机 第二版 第三章 。这本书还可以,不过好像也没什么其他中文的关于jvm比较好的书了

jvm要做垃圾回收时,首先要判断一个对象是否还有可能被使用。那么如何判断一个对象是否还有可能被用到?

如果我们的程序无法再引用到该对象,那么这个对象就肯定可以被回收,这个状态称为不可达。当对象不可达,该对象就可以作为回收对象被垃圾回收器回收。

那么这个可达还是不可达如何判断呢?

答案就是GC roots ,也就是根对象,如果从一个对象没有到达根对象的路径,或者说从根对象开始无法引用到该对象,该对象就是不可达的。

以下三类对象在jvm中作为GC roots,来判断一个对象是否可以被回收 
(通常来说我们只要知道虚拟机栈和静态引用就够了)

  • 虚拟机栈(JVM stack)中引用的对象(准确的说是虚拟机栈中的栈帧(frames)) 
    我们知道,每个方法执行的时候,jvm都会创建一个相应的栈帧(栈帧中包括操作数栈、局部变量表、运行时常量池的引用),栈帧中包含这在方法内部使用的所有对象的引用(当然还有其他的基本类型数据),当方法执行完后,该栈帧会从虚拟机栈中弹出,这样一来,临时创建的对象的引用也就不存在了,或者说没有任何gc roots指向这些临时对象,这些对象在下一次GC时便会被回收掉
  • 方法区中类静态属性引用的对象 
    静态属性是该类型(class)的属性,不单独属于任何实例,因此该属性自然会作为gc roots。只要这个class存在,该引用指向的对象也会一直存在。class 也是会被回收的,在面后说明
  • 本地方法栈(Native Stack)引用的对象

一个class要被回收准确的说应该是卸载,必须同时满足以下三个条件

  • 堆中不存在该类的任何实例
  • 加载该类的classloader已经被回收
  • 该类的java.lang.Class对象没有在任何地方被引用,也就是说无法通过反射再带访问该类的信息


这篇内容太少了,在说几句java中的四种引用类型

其实这四类引用的区别就在于GC时是否回收该对象

    • 强引用(Strong) 就是我们平时使用的方式 A a = new A();强引用的对象是不会被回收的
    • 软引用(Soft) 在jvm要内存溢出(OOM)时,会回收软引用的对象,释放更多内存
    • 弱引用(Weak) 在下次GC时,弱引用的对象是一定会被回收的
    • 虚引用(Phantom) 对对象的存在时间没有任何影响,也无法引用对象实力,唯一的作用就是在该对象被回收时收到一个系统通知
时间: 2024-10-23 23:31:47

jvm如何判断对象是否可以被回收的相关文章

JVM的判断对象是否已死和四种垃圾回收算法总结

面试题一:判断对象是否已死 判断对象是否已死就是找出哪些对象是已经死掉的,以后不会再用到的,就像地上有废纸.饮料瓶和百元大钞,扫地前要先判断出地上废纸和饮料瓶是垃圾,百元大钞不是垃圾.判断对象是否已死有引用计数算法和可达性分析算法. 1.引用计数算法 给每一个对象添加一个引用计数器,每当有一个地方引用它时,计数器值加 1:每当有一个地方不再引用它时,计数器值减 1,这样只要计数器的值不为 0,就说明还有地方引用它,它就不是无用的对象.如下图,对象 2 有 1 个引用,它的引用计数器值为 1,对象

JVM如何判断对象能否被回收

•写在前面 说起Java和C++,很容易想到让人疯狂的指针,Java使用了内存动态分配和垃圾回收技术,让我们从C++的各种指针问题中摆脱出来,更加专心于业务逻辑,不过如果我们需要深入了解java的JVM相关原理,我们必须要面对这些东西,深入了解JVM在内存动态分配和垃圾回收技术的原理知识,这篇文章就是来做一个先导,在jvm进行垃圾回收之前,它必须要知道回收的对象是否已“死”,这样才能保证程序的正常稳定. •对象的创建 我们将回收对象前,先讲讲在虚拟机上,对象是怎么被创建的.在我们编写代码的角度(

Java虚拟机如何判断对象已死?(哪些内存需要回收)

JVM管理的堆内存中,几乎存放了所有的对象实例,如果一个对象已经使用完毕(没有任何引用指向它),那么,该对象所占用的内存应该被回收利用,而这些工作就是JVM垃圾收集器的工作 垃圾收集器在对堆内存进行回收之前,第一件事情就是要确定哪些对象还"存活",哪些已经"死去",其内存将要被回收,下面就来讲--根搜索算法 在讲根搜索算法之前,因为一个对象在没有任何引用指向它的时候,其所占内存才具备回收添加,那我们先来讲讲什么事引用 传统意义的引用:如果reference类型的数据

JVM【第十回】:【判断对象已死之引用计数算法】

很多教科书判断对象是否存活的算法是这样的:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器都为0的对象就是不可能再被使用.很多应届生和一些有多年工作经验的开发人员,他们对于这个问题给予的都是这个答案. 客观地说,引用计数算法的实现建安,判定效率也很高,在大部分情况下它都是一个不错的算法,也有一些比较著名的应用案例,例如微软COM(Component Object Model)技术.使用ActionScript3的FlashPlayer

JVM【第十一回】:【判断对象已死之根搜索算法】

在主流的商用程序语言中(Java和C#)都是使用根搜索算法(GC Roots Tracing)判断对象是否存活的.这个算法的基本思路:通过一系列的名为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(就是从GC Roots到这个对象不可达)时,则证明对象是不可用的.如下图所示,对象object5.object6.object7虽然互相有关联,但是它们到GC Root

JVM理论:(二/2)判断对象是否已死

讲到垃圾回收,首先就要先知道哪些对象是可以回收的. 可达性算法 这里有必要先了解一下可达性算法,以"GC Roots"的对象作为起始点,若从"GC Roots"到某对象不可达时,此对象会被判定为可回收对象. 可作为GC Roots的对象包括下面几种: 1.虚拟机栈(栈帧中的本地变量表)中引用的对象. 2.方法区中类静态属性引用的对象. 3.方法区中常量引用的对象. ?有疑问 4.本地方法栈中JNI(native方法)引用的对象. * 作为扩展知识了解一下引用计数法,

JVM学习-jvm判断对象已死的方法

在堆里面存放着各种各类的Java对象,垃圾收集器在对堆进行垃圾回收时,首要就是判断哪些对象还活着,哪些对象已经死去(即不被任何途径引用的对象). 标记清除算法: 标记清除算法简单概括为:给对象添加一个引用计数器,每当有一个地方引用该对象时,计数器+1,当引用失效时,计数器-1,任何时刻,当计数器为0的时候,该对象不再被引用.客观的说,引用计数器的实现简单,判定效率也高,大部分场景下是一个不错的选择.但是,当前主流的Jvm均没有采用标记清除算法,原因在于,它很难解决对象之间互相循环调用的情况. 可

JVM高级特性-三、垃圾收集之判断对象存活算法

一.概述 运行时数据区中,程序计数器.虚拟机栈.本地方法栈都是随线程而生随线程而灭的 因此,他们的内存分配和回收是确定的,在方法或线程结束时就回收.而Java堆和方 法区则是不确定的,程序运行过程中创建对象的大小是不定的,只有在程序处于运行 期才能知道所需内存的大小 二.“存活算法” 要判断对象是否存活,主要有两种算法:引用计数法和可达性分析算法 引用计数法 引用计数法就是给对象加上一个引用计数器,每当对象被 引用一次 计数器值就加1,引用时效则减1,计数器为0则表示不会再被使用. 可达性分析算

JVM学习记录-对象已死吗

前言 先来回顾一下,在jvm运行时数据区,分为两部分,一个部分是线程共享区,主要包括堆和方法区,另一部是线程私有区分包括本地方法栈,虚拟机栈和程序计数器.在线程私有部分的三个区域是随着线程生和灭的.栈中的栈帧随着方法的进入和退出而执行着出栈和入栈操作.每一个栈帧所用内存大小在类结构确定下来时就已知了.因此这线程私有区的内存分配和回收都具备确定性,简单概括的说:这部分内存在类加载时分配,在线程结束时回收.(个人理解) 而线程共享区(堆和方法区)则不一样,一个方法中的多个分支需要的内存可能不一样,只