强引用,软引用,弱引用,虚引用代码示例

强引用

最常见的引用赋值Object object = new Object();,无论任何情况下,即使OOM,只有强引用关系还在,垃圾收集器就永远不会回收被该类对象。

    public static void StronglyReference() {
        byte[] object = new byte[ 1024 * 500 ];
        byte[] stranger = object;
        object = null;
        System.gc();// Full GC
        try {
            Thread.sleep(1000);//回收線程可能延遲
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(stranger);
    }

[B@1b6d3586

软引用

在内存不足时(老年代内存不足,即即将发生OOM,需要进行Full GC),垃圾收集器会将被软引用关联的对象回收。如果回收后还没有足够的内存,才抛出内存溢出异常(注意,如果回收后有足够空间就不报OOM)。
VM参数-Xms12m -Xmx12m,可知Eden是3.2M,老年代是8M

    /**
     * -Xms12m -Xmx12m
     * 新生代 :老年代 = 1 : 2
     * Eden : Survivor0 : Survivor1 = 8 : 1 : 1
     * 所以Eden是3.2M,老年代是8M
     */
    public static void SoftReferenceTest() {
        byte[] object = new byte[ 1024 * 500 ];// 500K,放到新生代
        SoftReference<Object> softReference = new SoftReference<>(object);
        object = null;
        System.gc();// 此時內存充足,軟引用不會被回收,Full GC放到老年代
        try {
            Thread.sleep(1000);//回收線程可能延遲
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("對象:" + softReference.get());

//        放一個大對象,超過老年代容量,老年代放不下,OOM
//        try {
//            byte[] newObject = new byte[ 1024 * 1024 * 8 ];// 8M
//        } catch (Throwable e) {// OOM
//            e.printStackTrace();
//        }

//        這時新對象剛好在老年代放得下,軟引用放不下,恰好被回收
//        byte[] newObject = new byte[ 1024 * 1024 * 7 ];

//        這時老年代放得下舊對象和新對象,軟引用不回收
        byte[] newObject = new byte[ 1024 * 1024 * 6 ];

        System.out.println("對象:" + softReference.get());
    }

新旧对象均放不下
對象:[B@1b6d3586
java.lang.OutOfMemoryError: Java heap space
      at com.jvm.Main.SoftReferenceTest(Main.java:44)
      at com.jvm.Main.main(Main.java:98)
對象:null

只能放新对象
對象:[B@1b6d3586
對象:null

新旧对象均能放得下
對象:[B@1b6d3586
對象:[B@1b6d3586

弱引用

被弱引用关联的对象只能生存到下一次垃圾收集发生为止。下一次垃圾收集时,不管当前内存是否足够,都会回收只被弱引用关联的对象。

    public static void WeakReferenceTest() {
        byte[] object = new byte[ 1024 * 1024 ];// 1M,放到新生代
        WeakReference<Object> weakReference = new WeakReference<>(object);
        object = null;
        System.out.println("對象:" + weakReference.get());
        System.gc();// 弱引用GC就回收
        try {
            Thread.sleep(1000);//回收線程可能延遲
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("對象:" + weakReference.get());
    }

對象:[B@1b6d3586
對象:null

虚引用

一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象的实例。为一个对象设置虚引用关联的唯一目的是为了能在这个对象被回收时收到一个系统通知。

    public static void PhantomReferenceTest() {
        Object object = new Object();//被回收的對象
        ReferenceQueue<Object> queue = new ReferenceQueue<>();
        //虛引用必須提供一個引用隊列,在對象被回收時通過引用隊列發送通知
        PhantomReference<Object> phantomReference = new PhantomReference<>(object, queue);
        System.out.println(phantomReference.get());// 無法通過虛引用獲取對象實例
        object = null;//不引用該對象
        System.gc();//回收
        try {
            Thread.sleep(1000);//回收線程可能延遲
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //虛引用被回收,可以在引用隊列找到該對象的信息
        PhantomReference<Object> phantom = (PhantomReference<Object>) queue.poll();
        if (phantom != null) {
            System.out.println("對象已回收:" + phantom);
        } else {
            System.out.println("對象未回收");
        }
    }

null
對象已回收:java.lang.ref.PhantomReference@1b6d3586

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值