java 如何判断对象可以回收?

垃圾回收机制

  • 如何判断对象可以回收?

    • 引用计数法:

      • 当存在引用时+1,减小引用时 -1;
      • 当引用数 = 0时,判断为垃圾;
      • 缺:当存在循环引用时,双方引用都是1,就不能判断垃圾;
    • 可达性分析算法:

    • 根对象:肯定不能当作垃圾进行回收的对象;

    • 当一个对象没有直接或间接被根对象引用,则就被当做垃圾。

    • 扫描堆中的对象,是否能沿着GC root对象为起点的引用链找到该对象,找不到的为垃圾;

    • 根对象【堆中的对象,不是引用变量】:

      • 系统核心类【System Class】:String,Object,各种表启动器加载类;
      • 操作系统的方类【Native Stack】:Class,
      • 线程类【Thread】:启动线程的类,栈帧;
      • 加锁的对象【Busy monitor】:Lock类
    • 四种引用:

      • 强引用:沿着GC root对象链能找到的对象,平时经常使用的方式;

      • 软引用:被强引用对象,软引用的对象,当垃圾回收后,内存还不够时,会被回收;

      • 弱引用:被强引用对象,弱引用的对象,当发生垃圾回收时,就会被回收;

        软、弱引用本身也是对象,当他们的引用的对象,被回收时,会被放入引用队列里【可以做进一步释放,也可以不放】;

        //引用队列,可放[自动放入],可不放;
        ReferenceQueue queue = new ReferenceQueue<>();
        SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB],queue);
        byte[] data = ref.get();
        
      • 虚引用【配合ByteBuffer使用】:直接内存和ByteBuffer存在虚引用,当ByteBuffer对象被回收的时候,虚引用被放入引用队列;引用队列存在一个线程【Reference Handler】,定时释放引用队列,【调用虚引用相关方法,释放直接内存】;

      • 终结器引用:每个对象都会继承finalize()方法,当没有直接引用时,会被放入引用队列【第一次回收时】,被一个Finalizer线程【优先级很低】调用对象的finalize()方法,第二次才能被当作垃圾释放;

        虚、终结引用必须配合引用队列使用;

posted @ 2025-03-08 12:12  烟雨断桥  阅读(43)  评论(0)    收藏  举报