2

这是我的问题 - 我想计算一个对象从给定点(可能是对象创建)开始存活多长时间(即在堆上)。我不需要记录这在死亡时有多长时间,只是在某个时刻。

我目前的想法是创建一个WeakReference记录开始和结束时间的扩展,即

public class WeakTimeReference extends WeakReference<Object> {

    private final long start;
    private long end = -1;;
    public WeakTimeReference(Object obj, ReferenceQueue<Object> queue){
        super(obj,queue);
        long = System.currentTimeMillis();      
    }

    public Long getLife(){ return (end == -1) ? null : end-start; }

}

然后将这些添加到一个WeakHashMap(这样我就可以知道我什么时候已经创建了一个引用),即

private Map<Object,WeakTimeReference> map = 
                   new WeakHashMap<Object,WeakTimeReference>();
private ReferenceQueue queue = new ReferenceQueue();
public void add(Object o){
    if(!map.containsKey(o))
        map.put(o,new WeakTimeReference(o,queue));
}

然后,当我想知道时间时,我只看queue

while(queue.poll()){
   WeakTimeReference ref = (WeakTimeReference) queue.remove();
   // do something with ref.getLife()
}

但是,问题是我不确定如何endWeakTimeReference. 没有方法可以覆盖,Reference当它入队时被调用,或者任何这样的方法ReferenceQueue

我唯一的想法是,我可以用一个类来包装对象,该类有一个finalize为我执行此操作的方法,并将它们放在WeakHashMap被包装对象指向的指针中。但这似乎很混乱。

所以我的问题是:

当参考对象被放置在参考队列上时,无论如何要执行操作?

如果做不到这一点,任何人都可以看到我实现这一目标的更简洁的方法吗?

4

2 回答 2

2

使用终结器,但您必须遵守此模式:

protected void finalize() throws Throwable
{
  try
  {
    // your code here
  }
  finally
  {
    super.finalize();
  }
}

或者你会尽可能地接近未定义的行为,因为你可以使用 Java。

于 2013-09-24T13:32:06.487 回答
1

使用带有回调处理程序的包装器,该处理程序将在对象被 GC 时通知观察者。

class Wrapper implements ObjectInterface {
   Object obj;
   Statistics statisics;
   long t0 = System.currentTimeMillis;
   ...
   protected finalize() {
      statisics.notify(obj, System.currentTimeMillis - t0);
   }
}

我认为 Spring AOP 可以很好地完成这项任务

于 2013-09-24T13:34:15.593 回答