私のアプリケーションは、特定のオブジェクトの使用状況をログに記録します。私のセットアップでは、AspectJ を使用して、関心のあるコンテキストを識別し、これらの使用状況をログに記録します。後でログ ファイルを読み込んで分析しますが、効率上の理由から、オブジェクトに到達できなくなった時点を把握しておくと便利です。
私の現在のアプローチは、関心のあるオブジェクトを「ガベージ ロガー」でログに記録することです。これにより、オブジェクトの ID ハッシュ コードを含む「セーバー」オブジェクトが作成され、これが弱いハッシュ マップに格納されます。オブジェクトが収集されると、セーバー オブジェクトが弱いハッシュ マップから削除されて収集され、収集されたオブジェクトの 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
}
私の問題は、これが非常に複雑に見えることです。スペースが必要でない限り、弱いハッシュ マップは必ずしもエントリをクリアするとは限らないため、オブジェクトが収集されてから記録するまでに長時間待機する可能性があります。基本的に、私はこれを達成するためのより良い方法を探しています。
注 - 私は任意のオブジェクトを監視しており、その作成を制御できないため、ファイナライズ メソッドをオーバーライドできません。