Java四种引用类型详解

本文详细介绍了Java中的四种引用类型:强引用、软引用、弱引用和虚引用,包括它们的概念、应用场景、引用队列以及源码解析。软引用在内存不足时会被回收,适合做内存缓存;弱引用在下次GC时回收;虚引用用于跟踪垃圾回收,通常与引用队列配合使用。此外,文章还探讨了引用队列的工作原理和软引用的回收策略。
摘要由CSDN通过智能技术生成

前言

为了满足对不同情况的垃圾回收需求,Java从版本1.2开始,引入了4种引用类型(其实是额外增加了三种)的概念。本文将详细介绍这四种引用。

Java 4种引用类型

Java中的4中引用类型分别为强引用(String Reference),软引用(Soft Reference),弱引用(Weak Reference)和虚引用(Phantom Reference)。

概念及应用场景

  • 强引用:Java中的引用,默认都是强引用。比如new一个对象,对它的引用就是强引用。对于被强引用指向的对象,就算JVM内存不足OOM,也不会去回收它们。
  • 软引用:若一个对象只被软引用所引用,那么它将在JVM内存不足的时候被回收,即如果JVM内存足够,则软引用所指向的对象不会被垃圾回收(其实这个说法也不够准确,具体原因后面再说)。根据这个性质,软引用很适合做内存缓存:既能提高查询效率,也不会造成内存泄漏。
  • 弱引用:若一个对象只被弱引用所引用,那么它将在下一次GC中被回收掉。如ThreadLocalWeakHashMap中都使用了弱引用,防止内存泄漏。
  • 虚引用:虚引用是四种引用中最弱的一种引用。我们永远无法从虚引用中拿到对象,被虚引用引用的对象就跟不存在一样。虚引用一般用来跟踪垃圾回收情况,或者可以完成垃圾收集器之外的一些定制化操作。Java NIO中的堆外内存(DirectByteBuffer)因为不受GC的管理,这些内存的清理就是通过虚引用来完成的。

引用队列

引用队列(Reference Queue)是一个链表,顾名思义,存放的是引用对象(Reference对象)的队列。
软引用弱引用可以和一个引用队列配合使用,当引用所指向的对象被垃圾回收之后,该引用对象本身会被添加到与之关联的引用队列中,从而方便后续一些跟踪或者额外的清理操作。
因为无法从虚引用中拿到目标对象,虚引用必须和一个引用队列配合使用。

案例解析

设置JVM的启动参数为

-Xms10m -Xmx10m

public class ReferenceTest {
   
    private static int _1MB = 1024 * 1024;
    private static int _1KB = 1024;

    public static void main(String[] args) throws InterruptedException {
   
        // 引用队列,存放Reference对象
        ReferenceQueue queue = new ReferenceQueue();
        // 定义四种引用对象,强/弱/虚引用为1kb,软引用为1mb
        Byte[] strong = new Byte[_1KB];
        SoftReference<Byte[]> soft = new SoftReference<>(new Byte[_1MB], queue);
        WeakReference<Byte[]> weak = new WeakReference<>(new Byte[_1KB], queue);
        PhantomReference<Byte[]> phantom = new PhantomReference<>(new Byte[_1KB], queue);

        Reference<String> collectedReference;
        // 初始状态
        System.out.println("Init: Strong Reference is " + strong);
        System.out.println("Init: Soft Reference is " + soft.get());
        System.out.println("Init: Weak Reference is " + weak.get());
        System.out.println("Init: Phantom Reference is " + phantom.get());
        do {
   
            collectedReference = queue.poll();
            System.out.println("Init: Reference In Queue is " + collectedReference);
        }
        while (collectedReference != null);
        System.out.println("********************");

        // 第一次手动触发GC
        System.gc();
        // 停100ms保证垃圾回收已经执行
        Thread.sleep(100);

        System.out.println("After GC: Strong Reference is " + strong);
        System.out.println
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值