Java中的各种引用(强引用、软引用、弱引用、虚引用)(四)

前言

Java中的各种引用(强引用、软引用、弱引用、虚引用)(一)
Java中的各种引用(强引用、软引用、弱引用、虚引用)(二)
Java中的各种引用(强引用、软引用、弱引用、虚引用)(三)
这里介绍一下弱引用

实现

弱引用通过WeakReference对象来实现

WeakReference<byte[]> reference1 = new WeakReference<>(new byte[1024 * 1024 * 3]);

特点

弱引用指向的对象在两种情况下会被立即回收掉:

  1. 内存不足
  2. 触发GC

TestCode

JVM设置
-Xms20M -Xmx20M -XX:+PrintGC
Test1 内存充足的情况,不触发GC

code

package com.test.application;

import java.lang.ref.WeakReference;

public class WeakReferences {

    public static void main(String[] args) throws InterruptedException {
        WeakReference<byte[]> reference1 = new WeakReference<>(new byte[1024 * 1024 * 3]);
        WeakReference<byte[]> reference2 = new WeakReference<>(new byte[1024 * 1024 * 4]);
        System.out.println(System.currentTimeMillis() + ":" + reference1.get());
        System.out.println(System.currentTimeMillis() + ":" + reference2.get());
        Thread.sleep(1000);
        byte[] big2 = new byte[3 * 1024 * 1024];
        System.out.println(System.currentTimeMillis() + ":" + reference1.get());
        System.out.println(System.currentTimeMillis() + ":" + reference2.get());
        System.out.println(System.currentTimeMillis() + ": " + big2);
    }
}

result

1604040001310:[B@140e19d
1604040001311:[B@17327b6
1604040002313:[B@140e19d
1604040002313:[B@17327b6
1604040002313: [B@14ae5a5
Test2 内存充足的情况下,触发GC

code

package com.test.application;

import java.lang.ref.WeakReference;

public class WeakReferences {

    public static void main(String[] args) throws InterruptedException {
        WeakReference<byte[]> reference1 = new WeakReference<>(new byte[1024 * 1024 * 3]);
        WeakReference<byte[]> reference2 = new WeakReference<>(new byte[1024 * 1024 * 4]);
        System.out.println(System.currentTimeMillis() + ":" + reference1.get());
        System.out.println(System.currentTimeMillis() + ":" + reference2.get());
        System.gc();
        Thread.sleep(1000);
        byte[] big2 = new byte[3 * 1024 * 1024];
        System.out.println(System.currentTimeMillis() + ":" + reference1.get());
        System.out.println(System.currentTimeMillis() + ":" + reference2.get());
        System.out.println(System.currentTimeMillis() + ": " + big2);
    }
}

result

1604040100543:[B@140e19d
1604040100543:[B@17327b6
[GC (System.gc())  8721K->4852K(19712K), 0.0009327 secs]
[Full GC (System.gc())  4852K->624K(19712K), 0.0030258 secs]
1604040101549:null
1604040101549:null
1604040101549: [B@14ae5a5
Test3 不触发GC,内存不足

code

package com.test.application;

import java.lang.ref.WeakReference;

public class WeakReferences {

    public static void main(String[] args) throws InterruptedException {
        WeakReference<byte[]> reference1 = new WeakReference<>(new byte[1024 * 1024 * 5]);
        WeakReference<byte[]> reference2 = new WeakReference<>(new byte[1024 * 1024 * 6]);
        System.out.println(System.currentTimeMillis() + ":" + reference1.get());
        System.out.println(System.currentTimeMillis() + ":" + reference2.get());
        Thread.sleep(1000);
        byte[] big2 = new byte[12 * 1024 * 1024];
        System.out.println(System.currentTimeMillis() + ":" + reference1.get());
        System.out.println(System.currentTimeMillis() + ":" + reference2.get());
        System.out.println(System.currentTimeMillis() + ": " + big2);
    }
}

result

1604040233187:[B@140e19d
1604040233188:[B@17327b6
[GC (Allocation Failure)  13068K->11996K(19712K), 0.0011080 secs]
[GC (Allocation Failure)  11996K->11980K(19712K), 0.0022058 secs]
[Full GC (Allocation Failure)  11980K->661K(19712K), 0.0046475 secs]
1604040234198:null
1604040234198:null
1604040234198: [B@14ae5a5
结果分析

从结果上看,只要GC被触发了,无论是手动触发的还是因为内存不足JVM自动执行的,弱引用的对象一定会被回收。

结论

与软引用不同的是,只要触发GC就会回收弱引用对象,而软引用对象只有在内存不足的时候才会彻底回收。
如果一个对象是偶尔(很少)的使用,并且希望在使用时能获取到,但又不想影响此对象的垃圾收集,那么就可以用Weak Reference来记住此对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值