java中的Reference,SoftReference,WeakReference,PhantomReference

java中的引用对象类型

java中的引用类型分别是强引用,SoftReference,WeakReference,PhantomReference。

在这里插入图片描述
我们平常中产生的对象绝大部分是强引用类型,下来来分别介绍。

java强引用对象

Object o = new Object;
String s = "aa";
等等。。。。。。。

特点

当内存不足,JVM开始通过垃圾回收器进行垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收,因为存在引用指向这它,我们平常创建的对象都是强引用对象。要将强引用对象回收,只需引用指向null即可,等待gc回收

java软引用对象(SoftReference)

这里我们启动程序的时候,为了出现内存不足现象,使用了jvm -XX参数。只需vm option配置即可
-XX:InitialHeapSize=10m -XX:MaxHeapSize=10m -XX:+PrintGCDetails

特点

1、当内存充足时,只要软引用对象还有引用指向,就不会被gc回收
2、当内存不充足时,不管软引用对象有没有被指向,都会被回收

public static void main(String[] args) {

        // 强引用对象
        Object s = new Object();

        // 软引用对象
        SoftReference<Object> softReference = new SoftReference<>(s);
        // 手动GC
        System.gc();

        System.out.println("内存充足时");
        System.out.println(s);
        System.out.println(softReference.get());

       try {
           s = null;
           // 当jvm堆内存不足时,会垃圾回收软引用对象
           byte[] buffer = new byte[35*1024*1024];
       }catch (Error e){
            e.printStackTrace();
       }finally {
           System.out.println("内存不充足时");
           System.out.println(s);
           System.out.println(softReference.get());
       }
    }

结果:

[GC (Allocation Failure) [PSYoungGen: 2048K->512K(2560K)] 2048K->842K(9728K), 0.0013049 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (System.gc()) [PSYoungGen: 1084K->512K(2560K)] 1414K->962K(9728K), 0.0010431 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 512K->0K(2560K)] [ParOldGen: 450K->853K(7168K)] 962K->853K(9728K), [Metaspace: 3313K->3313K(1056768K)], 0.0062308 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
内存充足时
java.lang.Object@6b884d57
java.lang.Object@6b884d57
[GC (Allocation Failure) [PSYoungGen: 81K->64K(2560K)] 934K->917K(9728K), 0.0007031 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 64K->128K(2560K)] 917K->981K(9728K), 0.0005246 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 128K->0K(2560K)] [ParOldGen: 853K->770K(5632K)] 981K->770K(8192K), [Metaspace: 3317K->3317K(1056768K)], 0.0077545 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] 770K->770K(9728K), 0.0003751 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 770K->752K(7168K)] 770K->752K(9728K), [Metaspace: 3317K->3317K(1056768K)], 0.0096544 secs] [Times: user=0.08 sys=0.00, real=0.01 secs] 
java.lang.OutOfMemoryError: Java heap space
	at com.xiaoxu.test_reference.ReferenceTest.main(ReferenceTest.java:28)
内存不充足时
null
null
Heap
 PSYoungGen      total 2560K, used 143K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
  eden space 2048K, 7% used [0x00000000ffd00000,0x00000000ffd23ee8,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
  to   space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
 ParOldGen       total 7168K, used 752K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
  object space 7168K, 10% used [0x00000000ff600000,0x00000000ff6bc158,0x00000000ffd00000)
 Metaspace       used 3360K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 369K, capacity 388K, committed 512K, reserved 1048576K

java弱引用对象(WeakReference)

特点

只要gc就会回收弱引用对象,不管弱引用对象,有没有引用指向

public static void main(String[] args) {

        // 强引用对象
        Object s = new Object();

        // weak引用对象
        Reference<Object> weakReference = new WeakReference<>(s);

        s=null;
        // 手动GC
        System.gc();

        System.out.println("内存充足时");
        System.out.println(s);
        System.out.println(weakReference.get());
    }

结果:

[GC (Allocation Failure) [PSYoungGen: 2048K->504K(2560K)] 2048K->856K(9728K), 0.0010334 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (System.gc()) [PSYoungGen: 1015K->496K(2560K)] 1368K->976K(9728K), 0.0011791 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 496K->0K(2560K)] [ParOldGen: 480K->849K(7168K)] 976K->849K(9728K), [Metaspace: 3273K->3273K(1056768K)], 0.0051562 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
内存充足时
null
null
Heap
 PSYoungGen      total 2560K, used 102K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
  eden space 2048K, 5% used [0x00000000ffd00000,0x00000000ffd19b38,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
  to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 ParOldGen       total 7168K, used 849K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
  object space 7168K, 11% used [0x00000000ff600000,0x00000000ff6d4630,0x00000000ffd00000)
 Metaspace       used 3303K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 361K, capacity 388K, committed 512K, reserved 1048576K

软引用和弱引用的适用场景

需要对图片进行大量缓存

1、如果每次读取图片都从硬盘读取则会严重影响性能

2、如果一次性全部加载到内存中,又可能造成内存溢出
此时使用软引用可以解决这个问题。

设计思路:使用HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占的空间,从而有效地避免了OOM的问题

Map<String, SoftReference<BitMap>> imageCache
 = new HashMap<String, SoftReference<Bitmap>>();

WeakHashMap存储虚引用对象

public static void main(String[] args) {
        myHashMap();
        System.out.println("==========");
        myWeakHashMap();
    }

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

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

        key = null;

        System.gc();

        System.out.println(map);
    }

    private static void myWeakHashMap() {
        Map<Integer, String> map = new WeakHashMap<>();
        Integer key = new Integer(1);
        String value = "WeakHashMap";

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

        key = null;

        System.gc();

        System.out.println(map);
    }

一旦回收,map为空

java虚引用对象(PhantomReference)

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

虚引用的主要作用是跟踪对象被垃圾回收的状态。仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白鸽呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值