定时对象的生命

时间:2013-09-24 13:23:26

标签: java weak-references

这是我的问题 - 我想计算一个对象在给定点(可能是对象创建)中存活多久(即在堆上)。我不需要在某个时刻记录它在死亡时的持续时间。

我目前的想法是创建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()
}

但问题是,我不确定如何在end中设置WeakTimeReferenceReference中没有方法可以在排队时调用,或ReferenceQueue中的任何此类方法。

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

所以我的问题是:

无论如何,当引用对象放在引用队列上时执行操作?

如果做不到,有人能看到一种更简洁的方式来实现这个目标吗?

2 个答案:

答案 0 :(得分:2)

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

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

或者您将获得与Java一样接近未定义的行为。

答案 1 :(得分:1)

使用带回调处理程序的包装器,当对象被GC时,它将通知Observer。

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

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