模块 java.base

包 java.lang.ref


java.lang.ref
提供引用对象类,支持与垃圾收集器进行有限程度的交互。程序可以使用引用对象来维护对某个其他对象的引用,这样后者的对象仍然可以被收集器回收。程序也可以安排在收集器确定给定对象的可达性已更改后的某个时间收到通知。

包装规格

reference object 封装了对某个其他对象的引用,以便可以像任何其他对象一样检查和操作引用本身。提供了三种类型的参考对象,每一种都比最后一种弱:softweakphantom。每种类型对应于不同级别的可达性,定义如下。软引用用于实现对内存敏感的缓存,弱引用用于实现不阻止其键(或值)被回收的规范化映射,幻引用用于安排事后清理操作。 Cleaner 可以注册和管理事后清理操作。

每个引用对象类型都由抽象基类 Reference 类的子类实现。这些子类之一的实例封装了对特定对象的单个引用,称为 referent 。每个引用对象都提供获取和清除引用的方法。除了清除操作之外,引用对象在其他方面是不可变的,因此不提供set操作。程序可以进一步对这些子类进行子类化,添加其目的所需的任何字段和方法,或者它可以不加更改地使用这些子类。

Notification

在创建引用对象时,程序可能会请求通过 registering 带有 reference queue 的适当引用对象来通知对象可达性的更改。在垃圾收集器确定引用对象的可达性已更改为与引用类型对应的值后的某个时间,它将清除引用并将其添加到关联的队列中。此时,参考被认为是 enqueued 。程序可以通过轮询或阻塞的方式从队列中删除引用,直到引用可用。引用队列由 ReferenceQueue 类实现。

已注册的引用对象与其队列之间的关系是单向的。也就是说,队列不会跟踪向其注册的引用。如果注册的引用本身变得不可访问,那么它永远不会被排队。使用引用对象的程序有责任确保只要程序对引用对象感兴趣,对象就可以访问。

虽然一些程序会选择专用于从一个或多个队列中移除引用对象并处理它们的线程,但这绝不是必需的。一种通常很有效的策略是在执行其他一些相当频繁的操作的过程中检查引用队列。例如,使用弱引用实现弱键的哈希表可以在每次访问表时轮询其引用队列。这就是 WeakHashMap 类的工作原理。因为 ReferenceQueue.poll 方法只是检查内部数据结构,所以这种检查不会增加哈希表访问方法的开销。

可达性

从最强到最弱,不同级别的可达性反映了对象的生命周期。它们在操作上定义如下:
  • 一个对象是 strongly reachable 如果某个线程可以在不遍历任何引用对象的情况下访问它。新创建的对象可以被创建它的线程强访问。
  • 一个对象是softly reachable如果它不是强可达但可以通过遍历软引用到达。
  • 一个对象是weakly reachable如果它既不是强可达也不是软可达但可以通过遍历弱引用到达。当对弱可达对象的弱引用被清除时,该对象就有资格进行终结。
  • 一个对象是 phantom reachable 如果它既不是强可达的,也不是弱可达的,它已经完成,并且有一些幻象引用引用它。
  • 最后,一个对象是 unreachable ,因此当它无法通过上述任何一种方式到达时,它有资格被回收。
自从:
1.2
  • 描述
    Cleaner 管理一组对象引用和相应的清理操作。
    Cleanable 表示在 Cleaner 中注册的对象和清洁操作。
    幻象引用对象,在收集器确定它们的引用对象可以以其他方式回收后排队。
    引用对象的抽象基类。
    引用队列,在检测到适当的可达性更改后,垃圾收集器将已注册的引用对象追加到该队列中。
    软引用对象,由垃圾收集器根据内存需求自行清除。
    弱引用对象,不阻止其引用对象可终结、终结,然后回收。