5

私のアプリケーションは、特定のオブジェクトの使用状況をログに記録します。私のセットアップでは、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
}

私の問題は、これが非常に複雑に見えることです。スペースが必要でない限り、弱いハッシュ マップは必ずしもエントリをクリアするとは限らないため、オブジェクトが収集されてから記録するまでに長時間待機する可能性があります。基本的に、私はこれを達成するためのより良い方法を探しています。

注 - 私は任意のオブジェクトを監視しており、その作成を制御できないため、ファイナライズ メソッドをオーバーライドできません。

4

2 に答える 2

3

より迅速な結果が得られる可能性のある (また、潜在的なボトルネックを軽減する) やや単純な代替手段は次のとおりSavingsです。

private final ConcurrentMap<WeakReference, Integer> savings = new ConcurrentHashMap<>();

public void run() {
    while(running) {
        for(WeakReference reference : savings.keySet()) {
            if(reference.get() == null) {
                log(savings.remove(reference));
            }
        }
        sleep(1000);
    }
}

欠点は、クリアされた参照を見つけるためにマップを継続的に反復する必要があることですが、利点は実装が単純でありreference.get() == null、オブジェクトがクリアされるとすぐに true になります (一方、クリアされたオブジェクトをa WeakHashMap)。を使用するConcurrentMapと、 の使用によって作成される可能性のあるボトルネックが緩和され、Collections.synchronizedMapさらに重要なことに、for-each ループが をスローするのを防ぐことができますConcurrentModificationException

于 2013-06-05T15:02:13.083 に答える