2009-08-04 73 views
5

我只是挖公地IO库周围的垃圾收集和发现这一点:等待特定对象

 
Keeps track of files awaiting deletion, and deletes them when 
an associated marker object is reclaimed by the garbage collector. 

这可以为FileCleaningTracker对象的文档中找到。

现在我只是好奇我怎么能自己做到这一点?我的代码如何检测垃圾收集器回收对象的时间?

回答

9

根据the source code,它使用PhantomReference类。根据文档:

幻影参考对象,它们在收集器之后入队确定其对象可能会被回收。 幻影引用最常用于以比Java最终化机制更灵活的方式安排验尸前清理操作。

如果垃圾收集器在某个时间点确定虚拟引用的引用是虚幻可访问的,那么在那个时候或稍后它会将引用排入队列。

为了确保可回收对象保持如此状态,可能不会检索到幻像引用的指示对象:幻像引用的get方法始终返回null。

与软引用和弱引用不同,幻数引用不会在垃圾收集器入队时自动清除。通过幻影引用可访问的对象将保持如此状态,直到清除所有这些引用或者自己无法访问。

PhantomReference构造函数接受两个参数:

referent - 对象的新的虚引用将是指

q - 与该参考将被登记,或为空如果队列不需要注册

q参数是一个inst类ReferenceQueue类。当referent变成虚拟可达时,PhantomReference将被添加到此ReferenceQueue。发生这种情况时,可以使用ReferenceQueue类的poll()remove()方法检索PhantomReference

例如:

T objectToWatch = ...; 
ReferenceQueue<T> referenceQueue = new ReferenceQueue<T>(); 
new PhantomReference<T>(objectToWatch, referenceQueue); 

// Later on, probably in another thread... 
Reference<? extends T> nextReference = referenceQueue.remove(); 
// Tidy up! 

注:PhantomReference有一个名为SoftReferenceWeakReference同级类,也可能是使用的。这些关系记录在java.lang.ref package documentation中。

1

不确定这是否真的回答你的问题,但是在回收资源之前调用对象的finalize()方法。

编辑:这意味着你可以发送消息到另一个对象来提醒它,或沿着这些线。

+4

不要为此目的使用终结器,或者如果可以避免使用终结器。无法保证在垃圾收集之后立即调用finalize()方法,甚至不会保证它将被调用(请参阅Effective Java 2nd Ed,第7项)。 java.lang.ref包是要走的路。 – Leigh 2009-08-04 15:03:13