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

简介: 如何判断一个对象是否是可回收

判断一个对象是否可回收

Java的内存管理子系统,是通过可达性分析算法来判定对象是否存活。


引用计数法


给对象添加一个引用计数器,每当有一个地方引用,计数器就加 1 。当引用失效,计数器就减 1 。任何时候计数器为 0 的对象就是不可能再被使用的。


引用计数法实现简单,效率高,但是目前主流的虚拟机中没有选择这个算法来管理内存,最主要的原因是它很难解决对象之前相互循环引用的问题。


相互引用:


/**
 * 将Main class设置为想要查看GC日志的类
 * VM options : -XX:+PrintGCDetails
 */
public class ReferenceCountingGC {
    public Object reference = null;
    private static final int _1MB = 1024 * 1024;
    /**
     * 这个成员变量的唯一意义就是占点内存,以便能够在GC日志中看清楚是否有回收过
     */
    private byte[] bigSize = new byte[2 * _1MB];
    public static void main(String[] args) {
        ReferenceCountingGC objectA = new ReferenceCountingGC();
        ReferenceCountingGC objectB = new ReferenceCountingGC();
        objectA.reference = objectB;
        objectB.reference = objectA;
        objectA = null;
        objectB = null;
        //假设在这行发生GC,objectA和objectB是否能够被回收
        System.gc();
    }
}
/**
 * [PSYoungGen: 8030K->872K(75776K)] 8030K->880K(249344K)
 * 如果使用引用计数算法,那么这两个对象将会无法回收。
 * 而现在两个对象被回收了,说明Java使用的不是引用计数算法来进行标记的。
 */


77241df2395546b6a63c3e37adc9d641.png

在Java领域,至少主流的Java虚拟机里面都没有选用引用计数算法来管理内存,主要原因是,必须要配合大量的额外处理才能保证正确的工作,比如单纯的引用计算很难解决对象之间相互循环引用问题。


可达性分析算法


通过一系列的称为 “GC Roots” 的对象作为起点集,从这些节点开始向下搜索,搜索过程所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连的话,则证明此对象时不可用的。


利用可达性分析算法判定对象是否可回收


对象object5,object6,object7虽然没有相互关联,但是他们到GC Roots是不可达的,因此他们判定为可回收对象


b4f7960216124fc1be9545f6125ecd91.png

Java技术体系里面。固定可作为GC Roots的对象包括一下几种:

  • 虚拟机栈中局部变量表中引用的对象
  • 在方法区中类静态属性引用对象,比如类的引用型静态变量
  • 方法区中的常量引用的对象
  • 本地方法栈中 JNI 中引用的对象(Native方法)
  • Java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻对象(NullPointException,OutOfMemoryError)等,还有一些类加载器
  • 所有被同步锁(synchronized关键字)支持的对象
    ception,OutOfMemoryError)等,还有一些类加载器
  • 所有被同步锁(synchronized关键字)支持的对象
  • 反映Java虚拟机内部情况的JMXBean,JVMTI中注册回调,本地代码缓存等。


相关文章
|
5月前
|
算法 Java
垃圾收集-判断对象的生死
垃圾收集-判断对象的生死
35 0
|
5月前
|
算法 Java 程序员
JVM-如何判断对象可以回收
JVM-如何判断对象可以回收
|
Java
如何判断一个对象是否存活?
如何判断一个对象是否存活?
73 0
|
5月前
|
算法 Java
JVM中判断对象是否需要回收的方法
JVM中判断对象是否需要回收的方法
|
存储 缓存 算法
13-大厂面试题:为什么要垃圾回收以及如何判断对象可以回收
接下来我们正式进入第二个系列,关于垃圾回收以及优化。
106 0
13-大厂面试题:为什么要垃圾回收以及如何判断对象可以回收
|
5月前
|
缓存 算法 Java
在JVM中 判定哪些对象是垃圾?
在JVM中 判定哪些对象是垃圾?
|
算法 安全 Java
18-动态对象年龄判断+空间分配担保规则+老年代回收算法
本文中用到的案例是接着上一篇文章继续的,如果有不清楚同学请先查看上一篇文章
140 0
 18-动态对象年龄判断+空间分配担保规则+老年代回收算法
|
Java
16-内存分配与回收策略-对象优先分配Eden+大对象进老年代
大多数情况下, 对象在新生代Eden区中分配。 当Eden区没有足够空间进行分配时, 虚拟机将发起一次Minor GC。HotSpot虚拟机提供了-XX: +PrintGCDetails这个收集器日志参数, 告诉虚拟机在发生垃圾收集行为时打印内存回收日志, 并且在进程退出的时候输出当前的内存各区域分配情况。 在实际的问题排查中, 收集器日志常会打印到文件后通过工具进行分析 。
112 0
16-内存分配与回收策略-对象优先分配Eden+大对象进老年代
|
算法 Java 关系型数据库
引用计数 vs 根可达算法:深入比较对象存活判定
引用计数 vs 根可达算法:深入比较对象存活判定
207 0
|
缓存 算法 Java
内存管理:判断对象是否存活
在堆里面存放着 Java 世界中几乎所有的对象实例,垃圾收集器在对 Java 堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”(“死去”即不可能再被任何途径使用的对象)。 有两种判断对象是否存活的算法:引用计数算法、可达性分析算法。
129 0
内存管理:判断对象是否存活