10

私はJavaでソフト参照と弱参照を処理することに慣れていませんが、メモリがいっぱいになるとhdd機能にオーバーフローを提供するGemfireのようなデータグリッドを処理するために使用されているため、原則を理解しています。おそらくソフト参照などを使用しています。推測してみて。

Guavaで私が理解していないのは、キーをソフト/ウィークにし、値をソフト/ウィークにするメソッドを提供することです。

たとえば、ソフト以外の値を使用してソフトキーを作成する意味は何でしょうか。つまり、ソフト参照が収集され始めると、そのキーでエントリを見つけることができなくなります。それでは、なぜ値をマップに残したいのでしょうか。

誰かが私たちにいくつかのユースケースを与えることができますか?

  • 弱いキー/ソフト値
  • 弱いキー/通常の値
  • ソフトキー/弱値
  • ソフトキー/通常値

ありがとう


編集 私の質問が十分に正確かどうかわからないので、知りたいのは次のとおりです。

  • キーが収集されると(弱い/ソフト)、値はどうなりますか(弱い/ソフトではない)
  • 値が収集されると(弱い/柔らかい)、キーはどうなりますか
  • 欠落している部分(キーまたは値)を持つエントリはキャッシュに保持されますか?
  • そして、そのようなエントリをキャッシュに残したい場合のユースケースはありますか。

編集: Kevin Bourillonの回答で説明したように、最後に、ソフトキーを使用しても意味がない理由を理解したと思います。理由は次のとおりです。

static class KeyHolder {
    final private String key;
    public KeyHolder(String key) {
        this.key = key;
    }
    public String getKey() {
        return key;
    }
    @Override
    public boolean equals(Object o) {
        KeyHolder that = (KeyHolder)o;
        boolean equality = this.getKey().equals(that.getKey());
        return equality;
    }
    @Override
    public int hashCode() {
        return key != null ? key.hashCode() : 0;
    }
    @Override
    public String toString() {
        return "KeyHolder{" +
                "key='" + key + '\'' +
                '}';
    }
}

public static void main(String[] args) {
    System.out.println("TESTING WEAK KEYS");
    testMap( new MapMaker().weakKeys().<KeyHolder,String>makeMap() );


    System.out.println("\n\n");
    System.out.println("TESTING SOFT KEYS");
    testMap(new MapMaker().softKeys().<KeyHolder, String>makeMap());


    System.out.println("\n\n");
    System.out.println("TESTING SOFT REFERENCES");
    KeyHolder key1 = new KeyHolder("toto");
    KeyHolder key2 = new KeyHolder("toto");
    SoftReference<KeyHolder> softRef1 = new SoftReference<KeyHolder>(key1);
    SoftReference<KeyHolder> softRef2 = new SoftReference<KeyHolder>(key2);
    System.out.println( "equals keys? " + key1.equals(key2) );
    System.out.println( "equals ref? " + softRef1.equals(softRef2) );
}

private static void testMap(Map<KeyHolder,String> map) {
    KeyHolder strongRefKey = new KeyHolder("toto");
    KeyHolder noStrongRefKey = new KeyHolder("tata");
    map.put(strongRefKey,"strongRef");
    map.put(noStrongRefKey,"noStrongRefKey");
    // we replace the strong reference by another key instance which is equals
    // this could happen for exemple in case of serialization/deserialization of the key
    noStrongRefKey = new KeyHolder("tata");
    System.gc();
    System.out.println( "strongRefKey = " + map.get(strongRefKey) );
    System.out.println( "noStrongRefKey = " + map.get(noStrongRefKey) );
    System.out.println( "keyset = " + map.keySet() );
}

このコードは次の出力を生成します。

TESTING WEAK KEYS
strongRefKey = strongRef
noStrongRefKey = null
keyset = [KeyHolder{key='toto'}]



TESTING SOFT KEYS
strongRefKey = strongRef
noStrongRefKey = null
keyset = [KeyHolder{key='tata'}, KeyHolder{key='toto'}]



TESTING SOFT REFERENCES
toto == toto -> true
equals keys? true
equals ref? false

ご覧のとおり、(非推奨の)ソフトキーマップでは、「tata」を含むKeyHolderがマップにまだ存在しています。ただし、新しく作成されたキーを使用してエントリを見つけることができないことに注意してください。 " new KeyHolder("tata");" これは、キーが有意義に等しいためですが、EqualsメソッドがGuavaでオーバーライドされていないため、それらの周りの参照ラッパーは等しくありません。 この場合、はい、softKeysは何の意味もありません。それを取得できるようにするには、そのキーへのID参照を絶対に保持する必要があるからです。

4

2 に答える 2

13

softKeys意味がないので、メソッドを削除しました。softValuesキャッシュの外部で他の方法でも値インスタンスに到達できないと仮定すると、ソフト参照が意味をなす唯一の方法です。

次に、使用法はweakKeys基本的に、キーのIDの同等性が必要かどうかに要約されます。キーがオーバーライドされ、そのequals同等の動作が必要な場合、それを使用することはできません。IDが必要な場合は、それを取得する方法です。キーへの他のすべての参照がGCされると、とにかくそのエントリを検索する方法がないため、削除することもできます。 。weakKeys

私は実際、いつweakValuesが役立つのか完全には明確ではなく、それを調査しようとしていました。これはおそらくweakKeys、オプション(たとえば、Integerキー)ではなく、値が通常、ある種のセッションオブジェクトなどの他の手段によって強く参照される場合ですが、そのオブジェクトがなくなると、誰も存在しないことを意味します。もうキャッシュでこれを探しています。とはいえ、そういう風に言うと少し遠慮がちです。

于 2012-06-11T14:55:41.237 に答える
2

Guava 以外の WeakHashMap は弱いキーに基づいており、キーが使用されなくなったときにエントリ全体を破棄します。したがって、「マップにとどまる値」はありません。これは、私がそのようなデータ構造から直感的に期待する種類の動作であり、収集されたソフト参照に対しても、Guava が同じように動作することを強く疑っています。

Java Collections ライブラリは、弱いキー / ソフト値または弱いキー / 弱い値ではなく、弱いキー / 通常の値のマップのみを提供することに注意してください。ハッシュマップは、実際のキーとキーへの弱い参照に対して同じように機能することを期待すべきではありません)。

私自身、WeakHashMap を使用して、別の場所のメカニズムによって時代遅れになる可能性のあるオブジェクトを、そのメカニズムに関係のない情報に関連付けました (正確には、最近の動きに関する情報との特定の衝突によって破壊される可能性のある動くボール)。これらの値はそのマップ用に特別に作成されたものであり、他の場所では参照されていません (ただし、キーがまだ存在している間にのみ呼び出すことができるメソッドでローカルに参照されている場合を除きます)。したがって、値への通常の参照以外のものを使用する必要はありませんでした。キーが廃止されると、値は参照されなくなり、ガベージ コレクション可能になります。

于 2012-06-11T09:33:41.103 に答える