私のアプリケーションは、特定のオブジェクトの使用状況を記録します。私のセットアップはAspectJを使用して、興味のあるコンテキストを識別し、これらの用途を記録します。後で分析のためにログファイルをロードしますが、効率的な理由から、オブジェクトがもはや到達可能でないときを知ることは有用です。オブジェクトがガベージコレクトされたときのロギング
私の現在のアプローチは、私が興味を持っているオブジェクトを「ガベージ・ロガー」で記録することです。このガベージ・ロガーは、オブジェクトのIDハッシュコードを含む「保護者」オブジェクトを作成し、弱いハッシュマップに格納します。アイデアは、オブジェクトが収集されると、弱いハッシュマップからセーバーオブジェクトが削除されて収集されるため、収集されたオブジェクトのアイデンティティハッシュコードを記録するコードを実行するということです。ガベージコレクタでボトルネックを起こさないように、別のスレッドとキューを使用します。ここではごみロガーのコードは次のとおりです。
public class GarbageLogger extends Thread {
private final Map<Object,Saver> Savings =
Collections.synchronizedMap(new WeakIdentityHashMap<Object,Saver>());
private final ConcurrentLinkedQueue<Integer> clearTheseHash =
new ConcurrentLinkedQueue<Integer>();
public void register(Object o){
Savings.put(o,new Saver(System.identityHashCode(o));
}
private class Saver{
public Saver(int hash){ this.hash=hash;}
private final int hash;
@Override
public void finalize(){
clearTheseHash.add(hash);
}
}
@Override
public void run(){
while(running){
if((clearTheseHash.peek() !=null)){
int h = clearTheseHash.poll();
log(h);
}
else sleep(100);
}
}
// logging and start/end code omitted
}
私の問題はスペースが必要とされない限り、弱いハッシュマップは、必ずしもそのエントリをクリアしないので、これはオブジェクトがされた後、私は長い時間を待っているかもしれませんが、非常に複雑なようで、ということですそれを記録する前に収集されます。基本的に、私はこれを達成するためのより良い方法を探しています。
注 - 私は任意のオブジェクトを監視しており、作成を制御できないため、finalizeメソッドをオーバーライドできません。
本当に欲しいものは[参照キュー](http://stackoverflow.com/a/14450693/869736)です。 –
私はWeakIdentityHashMapとConcurrentLinkedQueueをReferenceQueueに置き換えますが、収集された参照をポップしてログに記録するにはGarbageLoggerスレッドがまだ必要でしょうか? – selig
これは正しいです。 –