强引用、软引用、弱引用、虚引用

5 篇文章 0 订阅

强引用、软引用、弱引用、虚引用

1.前景提示
2.整体介绍
  • 打开JDK文档
    在这里插入图片描述
  • 可以看到Reference下面有三个子类:SoftReference软引用,WeakReference弱引用,PhantomReference虚引用
  • 也可以用idea打开类图来看他们之间的关系:
    在这里插入图片描述
3.详细介绍

3.1 强引用

  • 强引用就是我们平常创建对象实例的方式,比如:Object obj = new Objict(); obj就是强引用
  • 其实所谓强软弱虚,都是相对于JVM垃圾回收来说的
  • 强引用在面对JVM垃圾回收时,具体如下:
    在这里插入图片描述
  • 下面我们写个Demo:
    在这里插入图片描述
  • 这个Demo很简单,创建一个对象,让obj1指向它,然后再把obj1对obj2进行引用赋值。
  • 最后把obj1置空,开启GC垃圾回收,打印obj2
  • 运行结果:
    在这里插入图片描述
  • obj2还是好好的指向对象实例,这个Demo其实没什么值得说的,把它贴出来也只是跟后面的其他引用做对比

3.2 软引用

  • 软引用是一种相对于强引用弱化了一些的引用,需要用java.lang.ref.SoftRefrtence来实现。
  • 对于只有软引用的对象来说:

1,当系统内存充足时它不会被回收。

2,当系统内存不足时它会被回收。

  • Demo:
/**
 * 软引用Demo
 * 1.软引用在内存够用时不回收,不够用的时候回收
 * 2.demo正常时候运行
 * 3.在配置-Xms5m -Xmx5m -XX:+PrintGCDetails下运行
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/1/4
 */
public class SoftReferencrDemo {
    public static void main(String[] args) {

        Object obj1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(obj1);

        System.out.println(obj1);
        System.out.println(softReference.get());

        obj1 = null;
        System.gc();

        try {

            byte[] b = new byte[10 * 1024 * 1024];
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println(obj1);
            System.out.println(softReference.get());
        }

    }
}
  • 内存充足时运行结果:
    在这里插入图片描述
  • 在配置-Xms5m -Xmx5m -XX:+PrintGCDetails下,内存不足时运行结果:
    在这里插入图片描述
  • 软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用,内存够用的时候就保留,不高用就回收!

3.3 弱引用

  • 弱引用需要用java.lang.ref.WeakReference来实现,它比软引用的生存期更短。
  • 对于只有弱引用的对象来说,只要垃圾回收一运行,不管JVM的内存是否足够,都会回收该对象。
  • Demo:
/**
 * 弱引用
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/1/4
 */
public class WeakReferenceDemo {
    public static void main(String[] args) {
        Object obj = new Object();
        WeakReference<Object> weakReference = new WeakReference<>(obj);

        System.out.println(obj);
        System.out.println(weakReference.get());

        obj = null;
        System.gc();

        System.out.println(obj);
        System.out.println(weakReference.get());
    }
}
  • 运行结果:
    在这里插入图片描述
    -弱引用的使用场景:
    在这里插入图片描述
    3.3.1 WeakHashMap
    -WeakHashMap是一种弱引用map,内部的key会存储为弱引用,当jvm gc的时候,如果这些key没有强引用存在的话,会被gc回收掉
    -Demo:

/**
 * todo
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/1/4
 */
public class WeakHashMapDemo {
    public static void main(String[] args) {

        myHashMap();
        System.out.println("========================");
        myWeakHashMap();
    }
    private static void myHashMap(){
        HashMap<Integer,String> weakHashMap = new HashMap<>();
        Integer key = new Integer(1);
        String value = "test";
        weakHashMap.put(key,value);
        System.out.println(weakHashMap);
        key = null;

        System.out.println(weakHashMap);
        System.gc();
        System.out.println(weakHashMap+"\t"+weakHashMap.size());
    }

    private static void myWeakHashMap(){
        WeakHashMap<Integer,String> weakHashMap = new WeakHashMap<>();
        Integer key = new Integer(1);
        String value = "test";
        weakHashMap.put(key,value);
        System.out.println(weakHashMap);
        key = null;

        System.out.println(weakHashMap);
        System.gc();
        System.out.println(weakHashMap+"\t"+weakHashMap.size());
    }
}

  • 运行结果:
    在这里插入图片描述
  • WeakHashmap业务场景就是缓存,可以有效的节省内存,缓存丢失也不会出太大问题,可以再次获取。许多开源框架,例如tomcat等都使用了weakHashmap做为缓存处理。

3.4 虚引用

  • 虚引用需要java.lang.ref.PhantomReference来实现,至于它到底是个什么东西:
    在这里插入图片描述
  • 至于引用队列ReferenceQueue:
    在这里插入图片描述
  • Demo:
/**
 * 虚引用
 *
 * @author wangjie
 * @version V1.0
 * @date 2020/1/4
 */
public class PhantomReferenceDemo {
    public static void main(String[] args) throws InterruptedException {
        Object obj = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> phantomReference = new PhantomReference<>(obj,referenceQueue);

        System.out.println(obj);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());

        System.out.println("=====================");

        obj = null;
        System.gc();
        Thread.sleep(500);
        System.out.println(obj);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());

    }
}

  • 运行结果:
    在这里插入图片描述
  • 可以看到虚引用phantomReference.get()无论在垃圾回收前还是回收后都null;
  • 反而是引用队列,在gc垃圾回收后把虚引用的对象保存了下来。
  • 总结:
    在这里插入图片描述
    【完】
    注:文章内所有测试用例源码:https://gitee.com/wjie2018/test-case.git
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值