Java 的四种引用类型

本篇主要介绍Java强软弱虚引用的区别以及GC对他们执行怎样的操作。

首先介绍下为什么要有引用类型?

我们对于一个对象的坚挺程度的要求是不一样的,这通常表现为我们希望的垃圾回收器对它的回收时机的不同。对于一些比较重要的对象,我们希望垃圾回收器永远不去回收它(即使是内存不足的情况)。

其次介绍Java的四种引用类型

  • 强引用(Strong Reference)
    强引用就是我们平时写的新建对象的用法:
StrongReference strongReference = new StrongReference();

代码创建了一个StrongReference对象,并且在这个对象和 strongReference(句柄)之间建立了强引用的关系。
强引用是所有的引用里面最强的一种,只要这个引用还存在,那么垃圾回收器就绝对不会回收这个对象。即使内存已经不足,JVM宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

  • 软引用(Soft Reference)
    软引用在强度上弱于强引用,通过以下方式引用:
SoftReference<Object> softReference = new SoftReference<Object>(new Object());

当JVM中的内存不足的时候,垃圾回收器可以释放只被软引用所指向的对象。如果全部释放完这些对象之后,内存还不足,才会抛出OutOfMemory错误。因此,软引用非常适合于创建缓存,当系统内存不足的时候,缓存中的内容是可以被释放的。

  • 弱引用(Weak Reference)
    创建弱引用如下:
WeakReference<Object> weakReference = new WeakReference<Object>(new Object());

建立弱引用之后,通过weakReference.get()方法可以得到Object对象,由于弱引用并不能阻挡垃圾回收器对对象进行回收,如果此对象只有弱引用的话,有可能在使用get()方法时突然返回null。
弱引用的作用在于解决强引用所带来的对象之间在存活时间上的耦合关系。弱引用最常见的用处是在集合类中,在哈希表中一个键值对被放入到哈希表中之后,哈希表对象本身就有了对这些键和值对象的引用。如果这种引用是强引用的话,那么只要哈希表对象本身还存活,其所包含的键和值对象是不会被回收的。

  • 虚引用(Phantom Reference)
    虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,在任何时候都可能被垃圾回收器回收。

虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中,所以通过检查该队列里面的内容就知道一个对象是不是已经准备被回收。

最后一个注意点:虚引用需要结合引用队列使用

引用队列可以方便的获取到引用对象。在软引用和弱引用对象被添加到队列之前,其对实际对象的引用会被自动清空。通过引用队列的poll/remove方法就可以分别以非阻塞和阻塞的方式获取队列中的引用对象。

ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference<Object> phantomReference = new PhantomReference<>(new Object(), referenceQueue);

你可能感兴趣的:(Java)