模块 java.base
Package java.lang.ref
提供引用对象类,它支持与垃圾收集器的有限程度的交互。 程序可以使用引用对象来维护对某个其他对象的引用,使得后者对象仍然可以由收集器回收。 程序还可以安排在收集器确定给定对象的可达性已经改变之后的某个时间通知。
包装规格
引用对象封装对某个其他对象的引用,以便可以像任何其他对象一样检查和操作引用本身。 提供了三种类型的参考对象,每种都比最后一种弱 : 软 , 弱和幻像 。 每种类型对应于不同级别的可达性,如下所述。 软引用用于实现对内存敏感的高速缓存,弱引用用于实现规范化映射,这些映射不会阻止其键(或值)被回收,而虚拟引用用于调度事后清理操作。 验尸清理行动可由Cleaner
登记和管理。 每个引用对象类型由抽象基础Reference
类的子类实现。 这些子类之一的实例封装了对特定对象的单个引用,称为引用对象 。 每个参考对象都提供了获取和清除引用的方法。 除了清除操作之外,参考对象也是不可变的,因此不提供set
操作。 程序可以进一步子类化这些子类,添加为其目的所需的任何字段和方法,或者它可以使用这些子类而不进行更改。
通知
程序可以通过在创建参考对象时向参考队列 注册适当的参考对象来请求通知对象的可达性的变化。 在垃圾收集器确定引用对象的可达性已更改为与引用类型对应的值之后的某个时间,它将清除引用并将其添加到关联队列。 此时,该参考被认为是入队的 。 程序可以通过轮询或阻塞来删除队列中的引用,直到引用可用为止。 参考队列由ReferenceQueue
类实现。 已注册的参考对象与其队列之间的关系是片面的。 也就是说,队列不会跟踪向其注册的引用。 如果注册的引用本身无法访问,那么它将永远不会被入队。 使用引用对象的程序负责确保只要程序对其引用对象感兴趣,对象就可以保持可达。
虽然某些程序会选择专用线程从一个或多个队列中删除引用对象并处理它们,但这绝不是必要的。 通常运行良好的策略是在执行其他相当频繁的操作的过程中检查引用队列。 例如,每次访问表时,使用弱引用实现弱键的哈希表都可以轮询其引用队列。 这就是WeakHashMap
类的工作原理。 因为ReferenceQueue.poll
方法只是检查内部数据结构,所以此检查将为哈希表访问方法增加很少的开销。
可达性
从最强到最弱,不同的可达性水平反映了物体的生命周期。 它们在操作上定义如下:- 如果某个对象可以在不遍历任何引用对象的情况下到达某个对象,则该对象是强可访问的 。 新创建的对象可由创建它的线程强烈访问。
- 如果一个对象不能很容易到达,则可以轻柔地到达,但可以通过遍历软引用来访问该对象。
- 一个对象是弱可及 ,如果它是既不坚决也不是软可及的,但通过遍历弱引用可以到达。 当清除对弱可达对象的弱引用时,该对象就有资格进行最终化。
- 如果一个对象既没有强烈,柔和,也没有弱到达,则它是幻像可达的 ,它已经完成,并且一些幻像引用指的是它。
- 最后,如果无法通过上述任何方式访问对象,则无法访问该对象,因此有资格进行回收。
- 从以下版本开始:
- 1.2
-
接口摘要 接口 描述 Cleaner.Cleanable Cleanable
表示在Cleaner
注册的对象和清洁操作。 -
类摘要 类 描述 Cleaner Cleaner
管理一组对象引用和相应的清理操作。PhantomReference<T> 幻像引用对象,在收集器之后排队,确定它们的对象可以被回收。Reference<T> 引用对象的抽象基类。ReferenceQueue<T> 参考队列,在检测到适当的可达性更改后,垃圾收集器将附加的注册引用对象附加到该引用队列。SoftReference<T> 软参考对象,由垃圾收集器根据内存需求自行决定清除。WeakReference<T> 弱引用对象,它们不会阻止它们的指示物被最终化,最终化,然后回收。