提供引用对象类,它提供和GC有限的交互。
PhantomReference Phantom引用对象,在GC觉得它引用的对象能被回收后,把它入队。
Reference引用对象的基本抽象类
ReferenceQueue 引用队列,当GC发现引用可达性变化后把引用注册进此队列。
SoftReference Soft引用对象,GC根据内存状态进行回收。
WeakReferenceWeak引用对象,不妨碍它们的引用被终结,被回收。
提供引用对象类,它提供和GC有限的交互。程序可用使用引用类来引用其他对象,GC仍然可以对被引用的对象进行回收。程序还可以在给定对象可达性发生变化的时候得到通知。
包手册
一个引用对象封装其他引用对象,这样引用就可以随时测试和操作被引用的对象。这里提供了三种类型的引用,它们的引用程度逐渐变大,soft < weak < phantom。
每种类型都对应不同的可达性级别(下方的描述)。Soft引用常用在内存有限的缓存中,Weak引用常在k-v中使用,它们不阻碍k或者v被回收,使用Phantom引用
可以比先前使用Java finalization 机制实现更灵活的资源清理方法。
每种引用对象都是Reference类的子类.每一个实例都封装一个被引用的特定对象,叫做被引用对象。每个引用对象都提供get和clear方法来操作被引用的对象.
在clear操作执行以后,对象就不可再变化,所以不需要提供set方法。程序可以添加这些类的子类,添加任意字段和方法,或者不做任何改变。
通知
创建对象时注册引用对象,在对象的可达性发生变更后,程序即可得到通知。GC发现可达性改变后,根据引用的类型把引用加入到对应的队列,这个操作叫做入队。
程序可以使用轮询或者阻塞的方法从队列内移除引用。引用队列由ReferenceQueue类实现。
注册的引用对象和队列关系是单侧关系。队列并不保持被注册的引用。如果注册引用变成不可达,它将再不会入队。程序应该保证在需要引用对象的时候引用对象是可达到的。
在处理引用对象的时候,某些程序选择使用一个线程从一个或者多个队列中移除引用,这是没有必要的。不过,通过使用一些频繁的行为测试引用队列是一个不错的策略。比如,一个hashtable使用weak引用来实现key,这样在访问hashtable的时候可以通过轮询它的引用队列。这就是WeakHashMap实现的方式。因为ReferenceQueue.poll仅仅只检查内部的数据结构,这个检查只有一点很小的消耗。
自动清理引用
在添加到注册队列之前,Soft和Weak引用会自动被GC清理,因此,Soft和Weak引用不需要像Phantom引用一样注册到队列。通过Phantom可达的对象会一直存在,直到清除这个引用或者它们变成不可达为止。
可到达性
从最强到最弱,不同的可达性级别反应了不同的对象生命周期。它们的定义如下:
强可达到性:线程不用遍历引用链就可以访问到的引用,新建的对象对于建立它的对象就是强可达到性。
软可达到性:不是强可到达性,但是可以用通过遍历软引用链到达。
弱可达到性: 也不是强可达到性也不是软可到达性,但是它可以通过遍历弱引用链到达。当弱引用被清理后就变成弱可达性对象,这种对象符合终结条件。
幽灵可达到性:既不是强可达性,也不是软可到达性,也不是弱可达性,它已经被确定为垃圾,但是某个Phantom引用仍在指向它。
最后,如果一个对象不可到达,并且通过以上方法都不可达到,它是可以被回收。