Java中四种引用

作为Java工程师,在面试时,经常会被问道,强引用、软引用、弱引用,虚引用有什么区别以及应用场景?或者聊聊Java都有哪几种引用以及它们的应用场景?

其实这个问题,本身不难,但是由于在日常工作或者开发时,很少用到,以至于大家对其概念比较模糊,记不住。在这,总结一下,方便自己以后查询以及加深记忆。

首先,不同引用类型,主要体现的是对象不同的可达性状态和对垃圾回收的影响。

强引用(StrongReference),最普通的对象引用,只要还有强引用指向一个对象,就能表明对象还“或者”,垃圾回收器不会回收这个对象。当引用赋值为null,表明这个对象可以被垃圾收集了,具体的回收时机要看垃圾收集策略。强引用有如下特点:

  • 强引用可以直接访问目标对象。
  • 强引用所指向的对象在任何时候都不会被系统回收。
  • 强引用可能导致内存泄漏。
软引用(SoftReference),是一种相对于强引用弱化一些的引用,可以让对象豁免一些垃圾收集,当JVM认为内存不足时,才会试图回收软引用指向的对象。JVM会确保在抛出OOM之前,清理软引用指向的对象。软引用通常用来实现内存敏感的缓存,如果还有内存,就可以暂时保留缓存,当内存不足时清理掉,这样就能保证使用缓存的同时,不会耗尽内存。
SoftReference<Bean> bean = new SoftReference<Bean>(new Bean("name", 10)); 
System.out.println(bean.get());// “name:10”

软引用有以下特征:

  • 软引用使用 get() 方法取得对象的强引用从而访问目标对象。
  • 软引用所指向的对象按照 JVM 的使用情况(Heap 内存是否临近阈值)来决定是否回收。
  • 软引用可以避免 Heap 内存不足所导致的异常

弱引用(WeakReference)并不能使对象豁免垃圾收集,仅仅是提供一种访问在弱引用状态下对象的途径。这就可以用来构建一种没有特定约束的关系,比如,维护一种非强制性的映射关系,如果试图获取时对象还在,就使用它,否则重新实例化。它同样是很多缓存实现的选择。

弱引用有以下特征:

  • 弱引用使用 get() 方法取得对象的强引用从而访问目标对象。
  • 一旦系统内存回收,无论内存是否紧张,弱引用指向的对象都会被回收。
  • 弱引用也可以避免 Heap 内存不足所导致的异常。

虚引用(PhantomReference),也叫幻象引用,通过PhantomReference类来实现。无法通过虚引用访问对象的任何属性或函数。幻象引用仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取一些程序行动。

ReferenceQueue<String> refQueue = new ReferenceQueue<String>();
PhantomReference<String> referent = new PhantomReference<String>(new String("T"), refQueue);
System.out.println(referent.get());// null

可用来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。

引用:极客时间-Java核心技术36讲-第四讲

猜你喜欢

转载自blog.csdn.net/firefish001/article/details/80950160