Java四种引用方式

Java四种引用方式

强引用

class TestReference{
    
    // 方便垃圾回收时显示
    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalize");
    }
}


public static void main(String[] args) {
    // 强引用
    TestReference ref = new TestReference();
    System.out.println(ref);
    System.gc();
    System.out.println(ref);
}

当主动调用垃圾回收时,强引用不会被回收。

软引用

public static void main(String[] args) {
    
    SoftReference<byte[]> ref = 
       	 new SoftReference<>(new byte[1024 * 1024 * 5]);
    System.out.println(ref.get());
    System.gc();
    System.out.println(ref.get());
    byte[] buffer = new byte[1024 * 1024 * 10];
    System.out.println(ref.get());
}

形如new byte[]的是软引用,未赋值到某个变量,软引用当堆内存足够时不会被垃圾回收,但是当内存空间不够时会被回收。

下面是运行结果,设置了堆最大为15M。使用-Xmx参数设置。

[B@1540e19d
[B@1540e19d
null

弱引用

public static void main(String[] args) {
    WeakReference<TestReference> ref = 
        new WeakReference<>(new TestReference());
    System.out.println(ref.get());
    System.gc();
    System.out.println(ref.get());
}

弱引用当垃圾回收发生时,无论堆内存是否足够则都会被回收。

下面运行结果。

com.test.TestReference@1540e19d
null
finalize

虚引用

虚引用的使用需要搭配引用队列来使用,下面例子创建了一个虚引用,但是通过get()方法无法获取引用值,当虚引用被回收后,会进入引用队列中。

private static final List<Object> TEST_DATA = 
    new LinkedList<>();
private static final ReferenceQueue<TestReference> QUEUE = 	   new ReferenceQueue<>();

public static void main(String[] args) {
    TestReference obj = new TestReference();
    // 虚引用
    PhantomReference<TestReference> phantomReference = new PhantomReference<>(obj, QUEUE);

    // 该线程不断读取这个虚引用,并不断往列表里插入数据,以促使系统早点进行GC
    new Thread(() -> {
        while (true) {
            TEST_DATA.add(new byte[1024 * 100]);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }
            System.out.println(phantomReference.get());
        }
    }).start();

    // 这个线程不断读取引用队列,当弱引用指向的对象呗回收时,该引用就会被加入到引用队列中
    new Thread(() -> {
        while (true) {
            Reference<? extends TestReference> poll = QUEUE.poll();
            if (poll != null) {
                System.out.println("--- 虚引用对象被jvm回收了 ---- " + poll);
                System.out.println("--- 回收对象 ---- " + poll.get());
            }
        }
    }).start();

    obj = null;

    try {
        Thread.currentThread().join();
    } catch (InterruptedException e) {
        e.printStackTrace();
        System.exit(1);
    }
}

虚引用参考博客: https://www.cnblogs.com/mfrank/p/9837070.html

总结

4种引用由强到弱分别是强引用、软引用、弱引用、虚引用,软引用可用于缓冲,当内存空间不足时自动回收。虚引用可以用于做堆外内存的释放。

理解有限,如果有不对的地方还望指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值