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));
}

次に、時間を知りたいときは、queueieを見るだけです

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

endただし、問題は、どのように設定するのかわからないことですWeakTimeReference. エンキューされたときに呼び出されるオーバーライドするメソッド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 に答える