当前位置: 首页 > article >正文

Java 四种引用类型

文章目录

  • 前言
  • 一、整体架构
  • 二、强引用(Reference)
  • 三、软引用(SoftReference)
  • 四、弱引用(WeakReference)
  • 五、虚引用(PhantomReference)
  • 六、引用队列(ReferenceQueue)

前言

对Java 四种引用的学习,予以记录!

一、整体架构

在这里插入图片描述

强引用(Reference)
软引用(SoftReference)
弱引用(WeakReference)
虚引用(PhantomReference)
引用队列(ReferenceQueue)

位于java.lang.ref.*:Java提供了四种引用类型,在垃圾回收时,各自有各自的特点。ReferenceQueue是用来配合引用工作的,前三种没有ReferenceQueue一样可以运行

二、强引用(Reference)

默认支持模式,怎么都不回收

当内存不足,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收,死都不收。

强引用是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还"活着",垃圾回收器不会碰这种对象。在Java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不能被垃圾回收机制回收的,即使该对象以后永远都不会被用到JVM也不会被回收。因此强引用是造成Java内存泄漏的主要原因之一。

对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,一般就可以被垃圾收集得了(但具体回收时机要看垃圾收集策略)

public class StrongReferenceDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        Object o2 = o1;
        System.out.println(o2);

        o1 = null;
        System.out.println(o2);
        System.gc();
        System.out.println(o2);
    }
}

在这里插入图片描述

三、软引用(SoftReference)

当内存足够的情况下,不会回收,当内存不足的情况下,会回收

软引用是一种相对强引用弱化了一些的引用,需要用java.lang.ref.SoftReference类来实现,可以让对象豁免宜些垃圾收集。

对于只有软引用的对象来说,
当系统内存充足时它不会被回收
当系统内存不足时它会被回收

软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用,内存够用的时候就保留,不够用就回收

public class SoftReferenceDemo {
    public static void main(String[] args) {
        softRef_Memory_Enough();
        softRef_Memory_NotEnough();
    }

    /**
     * 内存够用时就保留,不够用就回收
     */
    private static void softRef_Memory_Enough() {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(softReference.get());

        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(softReference.get());
    }

    /**
     * JVM配置,故意产生大对象并配置小的内存,让它内存不够用了导致OOM,查看软引用地回收情况
     * -Xms5m -Xmx5m -XX:+PrintGCDetails
     */
    private static void softRef_Memory_NotEnough() {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(softReference.get());

        o1 = null;
        try {
            byte[] bytes = new byte[30 * 1024 * 1024];
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println(o1);
            System.out.println(softReference.get());
        }
    }
}

在这里插入图片描述

在这里插入图片描述

四、弱引用(WeakReference)

不管内存是否够用,只要是弱引用,只要发生GC,则被回收

public class WeakReferenceDemo {
    public static void main(String[] args) {
        testHashMap();
        System.out.println("========================");
        testWeakHashMap();
    }

    private static void testWeakHashMap() {
        Map<Integer, String> weakHashMap = new WeakHashMap<>();
        Integer key = new Integer(2);
        String value = "weakHashMap";

        weakHashMap.put(key, value);
        System.out.println(weakHashMap);

        key = null;
        System.out.println(weakHashMap);

        System.gc();
        System.out.println(weakHashMap + "\t" + weakHashMap.size());
    }

    private static void testHashMap() {
        Map<Integer, String> hashMap = new HashMap<>();
        Integer key = new Integer(1);
        String value = "hashMap";

        hashMap.put(key, value);
        System.out.println(hashMap);

        key = null;
        System.out.println(hashMap);

        System.gc();
        System.out.println(hashMap + "\t" + hashMap.size());
    }
}

在这里插入图片描述

在这里插入图片描述

五、虚引用(PhantomReference)

又称为幽灵引用,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象地生命周期。

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,它不能单独的使用也不能通过它访问对象,虚引用必须和引用队列(ReferenceQueue)联合使用

虚引用的主要作用时跟踪对象被垃圾回收的状态,仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。
PhantomReference的get方法总是返回null,因此无法访问对应的引用对象。其意义在于说明一个对象已经进入finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作。

换句话说,设置虚引用关联的唯一目的,就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步的处理。

Java技术允许使用finalize方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
在这里插入图片描述

public class PhantomReferenceDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> phantomReference = new PhantomReference<>(o1, referenceQueue);

        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());
        System.out.println("==============");

        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());
    }
}

在这里插入图片描述

六、引用队列(ReferenceQueue)

我被回收之前需要被引用队列保存下

在这里插入图片描述

public class ReferenceQueueDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        WeakReference<Object> weakReference = new WeakReference<>(o1, referenceQueue);
        System.out.println(o1);
        System.out.println(weakReference.get());
        System.out.println(referenceQueue.poll());
        System.out.println("==============");
        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(weakReference.get());
        System.out.println(referenceQueue.poll());
    }
}

在这里插入图片描述


http://www.kler.cn/a/108698.html

相关文章:

  • Fastapi使用MongoDB作为数据库
  • 【Pikachu】目录遍历实战
  • Springboot 启动端口占用如何解决
  • STM32嵌入式闹钟系统设计与实现
  • Java 堆内存管理详解:`-Xms` 和 `-Xmx` 参数的使用与默认内存设置
  • 深入剖析【C++继承】:单一继承与多重继承的策略与实践,解锁代码复用和多态的编程精髓,迈向高级C++编程之旅
  • 【网络协议】聊聊TCP如何做到可靠传输的
  • redis 常用方法
  • 71 搜索二维矩阵
  • 大数据之LibrA数据库常见术语(十)
  • Springmvc 讲解(1)
  • 嵌入式开发
  • Animate(原Flash)和木疙瘩中遮罩动画秒懂
  • 黑客在Pwn2Own Toronto上以58个零日漏洞赚取超过100万美元
  • dump与strace命令实战之分析keystore死锁导致watchdog问题
  • 正向代理和反向代理
  • 基于springboot实现校园疫情防控系统项目【项目源码+论文说明】计算机毕业设计
  • 【多线程面试题 八】、说一说Java同步机制中的wait和notify
  • 如何借助数据集更好的评估NLP模型的性能?
  • 【数据结构】数组和字符串(九):稀疏矩阵的链接存储:十字链表的插入、查找、删除操作
  • 大数据可视化BI分析工具Apache Superset实现公网远程访问
  • 【数据结构】Map和Set
  • 深入浅出排序算法之基数排序
  • OS的Alarm定时器调度机制
  • oracle,CLOB转XML内存不足,ORA-27163: out of memory ORA-06512: at “SYS.XMLTYPE“,
  • Think-Queue3一直提示[Exception]redis扩展未安装