3

私の質問は次のとおりです。一連の値を一連のキーに関連付けるにはどうすればよいですか。

  • キーを直接変更せずに、
  • キーがGCされるのを妨げることなく(値がキーを強く参照していることを知っている)

バックグラウンド:

一連の複雑なオブジェクト(値と呼びます)をいくつかの特定のオブジェクト(キーと呼びます)に関連付ける必要があります。

通常、これを行う方法は、キーと値を関連付けるハッシュマップを使用することです。

これはうまくいきます。ただし、マッピングがキーのガベージコレクションに干渉しないようにする必要もあります。つまり、マッピングが存在しても、キーがガベージコレクションされるのを防ぐことはできません。

通常、これを解決する方法は、キーへのWeakReferencesのみを保持するWeakHashMapを使用することです。ただし、WeakHashMapsは、マップ内の値にキーへの強力な参照がない場合にのみ機能します。残念ながら、私の値はすべて私のキーを強く参照しているため、キーがガベージコレクションされるのを防ぎます。これは、値の弱参照を使用することでも回避できますが、キーの前に値をGCすることを許可できないため、これは実行可能な解決策ではありません。キーオブジェクトがまだ存在している限り、値も存在する必要があります。

したがって、この状況に対する私の典型的な解決策は、HashMapの使用を停止し、代わりに、必要なすべての値への強力な参照を持つようにキーを変更することです。これにより、特定のキーのすべての値を取得できるようになりますが、自然なライフサイクルが完了したときにキーがGCされるのを防ぐことはできません。

残念ながら、キーを変更できないため、キーに直接値を追加することはできません。では、他にどのような賢い解決策がありますか?

4

2 に答える 2

2

制約がある場合:

  • キーには、値への何らかの参照があります
  • 値はキーを強く参照しています
  • キーがGCされるのを妨げないでください
  • キーの前に値をGCすることはできません
  • 値のキーが存在する限り、その値も存在する必要があります
  • 値とキーは引き続きGC対応である必要があります

...これは論理的には不可能だと思います。

値→キーマッピングを削除して(または少なくとも参照的に異なるが論理的.equal()にオブジェクトを使用して)、WeakHashMapソリューションを実行できないのはなぜですか?

于 2012-04-17T18:08:40.397 に答える
0

基本的に問題の解決策は次のとおり
です。 1.値からキーへの弱い参照を維持して、キーをGCできるようにします
2. WeakHashMapを使用してキーを値にマップしますそのキーへの強い参照)。

以下は、上記の設計を説明するためのサンプル アプリケーションです。

public class WeakApp {

WeakHashMap<Key,Value> weakHashMap = new WeakHashMap<Key,Value> ();
ArrayList <Key> strongReferences = new ArrayList<Key>();

static class Key {
    String smthg = "key";
    public Key(int count) {
        smthg = smthg + count;
    }

    public int hashCode() {
        return smthg.hashCode();
    }

     protected void finalize() {
         System.out.println("Key object " + smthg + " Gc'd");
     }
}

static class Value {

    static int count = 0;
    WeakReference keyReference = null ;
    String smthgValue = "Value object of key ";

    public Value(Key key) {
        keyReference = new WeakReference(key);
        count++;
        smthgValue = smthgValue + key.smthg;

    }
    protected void finalize() {
         System.out.println(" " + smthgValue + " Gc'd");
     }
}

void initValueToKeys(){
    for(int i =0; i< 10; i ++) {
        Key key = new Key(i);
        strongReferences.add(key);
        Value value = new Value(key);
        weakHashMap.put(key, value);
    }
    System.out.println("Weak hash Map size is " + weakHashMap.size());
}

void doMain() {

    System.gc();
    System.runFinalization();

    //Now slowly remove the strong reference keys simulating them going out of use
    Iterator<Key> itr = strongReferences.iterator();

    while(itr.hasNext()){
        Key key = itr.next();
        System.out.println("Removing strong reference to key " + key );
        itr.remove();

    }

    System.gc();
    System.runFinalization();

//shows if any values have references still from keys(should be 0), and expunges stale values to be Gc'd        
    System.out.println("Weak hash Map size is " + weakHashMap.size());

    //give chance for gc to remove the values 
    try {
        Thread.sleep(1000);
    }
    catch(Exception e){
        e.printStackTrace();
    }

    System.gc();
    System.runFinalization();

    System.out.println("System exited");
}

public static void main(String[] args) {
    WeakApp weakApp = new WeakApp();
    weakApp.initValueToKeys();
    weakApp.doMain();
}

}

よろしくオースティン

于 2012-12-01T11:54:33.133 に答える