6

WeakHashMap は、対応するキーがプログラムのどのセクションからも参照されなくなった場合に、値オブジェクトのメモリを Grabage Collector によって再利用できる Map インターフェイスの実装です。そのため、キーがプログラムで使用されなくなった場合。その Entry オブジェクトは、その使用法に関係なくガベージ コレクションされます。ここまでクリア

これは、キーが参照されなくなっても値オブジェクトが HashMap に残る HashMap とは異なります。値を削除するには、HashMap オブジェクトで remove() メソッドを明示的に呼び出す必要があります。remove を呼び出すと、エントリがマップから削除されるだけです。GC の準備ができているかどうかは、プログラムのどこかでまだ使用されているかどうかによって異なります。

上記で説明したこのコーディング例を見つけてください

私の理解によると、HashMap に対する WeakHashMap の使用

私の理解では、プログラムのどのセクションでもキーが参照されなくなったときに、値オブジェクトがGrabage Collectorによって確実に回収されるようにしたい場合にのみ、WeakHashMapを使用する必要があります。これにより、プログラムのメモリが効率的になります。私の理解は正しいですか?

JavaDocsに従って WeakHashMap を使用すると、このステートメントを見つけることができます

このクラスは主に、equals メソッドが == 演算子を使用してオブジェクトの同一性をテストするキー オブジェクトで使用することを目的としています。

上記のステートメントの意味と、それが WeakHashMap の使用法に関する私の理解とどのように対照的であるかがわかりませんでした。実際、このステートメントが WeakHashMap の使用にどのように関連しているかわかりませんでしたか?

更新:- 以下のステートメントをさらに注意深く読んで、javadocs

WeakHashMap のエントリは、そのキーが通常使用されなくなったときに自動的に削除されます。より正確には、特定のキーのマッピングが存在しても、キーがガベージ コレクターによって破棄されること、つまり、ファイナライズ可能になり、ファイナライズされてから再利用されることを防ぐことはできません。キーが破棄されると、そのエントリは事実上マップから削除されるため、このクラスは他の Map 実装とは多少異なる動作をします。

私は自分と他の人の利益のために自分の理解を修正しています

私の改訂された理解によると、HashMapを介したWeakHashMapの使用

キーがマップ自体以外で通常使用されなくなったときに、GC 実行時にキーと値のペアがマップから確実に削除されるようにする場合にのみ、WeakHashMap を使用する必要があります。

例は次のとおりです:-

    WeakHashMap<Integer, String> numbers = new WeakHashMap<Integer, String>();
    numbers.put(new Integer(1), "one");// key only used within map not anywhere else
    numbers.put(new Integer(2), "two");
    System.out.println(numbers.get(new Integer(1))); // prints "one"
    System.gc();
    // let's say a garbage collection happens here
    System.out.println(numbers.get(new Integer(1))); // prints "null"
    System.out.println(numbers.get(new Integer(2))); // prints "null"


    Object key = new Object();
    m1.put(key, c1);
    System.out.println(m1.size());
    key = null or new Object() ; // privious key only used within map not anywhere else
    System.gc();
    Thread.sleep(100);
    System.out.println(m1.size());
4

5 に答える 5

2

これは、オブジェクトがプログラムの他の部分からの強い参照を持たなくなったときに、オブジェクトがガベージ コレクション (GC) されるためです。

WeakHashMap<MyObject, String>次のようにすれば、 thenが与えられます。

MyObject mo = new MyObject();
map.put(mo, "Test");
mo = null;

その後、エントリーmo -> Testは GC の対象となります。これは、.equalsあるプロパティを使用しMyObjectて等しいかどうかをテストするカスタム実装がある場合、後でこれを行うことができないことを意味します。

MyObject mo2 = new MyObject();
map.get(mo2);

オーバーライドされた.equalsメソッドはそうmo2.equals(mo) == trueではないと言うかもしれませんがmo2 == mo、したがって、エントリはすでにGCされている可能性があります。

ポイントは、参照を保持し、moそれを使用して から値を取得するMap場合、その参照が必要であり== mo、したがって 2 つのことが当てはまるということです。

  1. エントリmo -> Testを gced できません
  2. ==ベースの.equalsメソッドを使用して、マップからエントリを取得できます

基本的; .equalsGC は強い参照を使用してオブジェクトを GC できるかどうかをテストするため、混乱を避けるためにメソッドが同じことを行うようにするのが最善です。

于 2013-12-23T12:01:20.003 に答える
1

このテストを実行する

    Object key = new Object();
    WeakHashMap m = new WeakHashMap();
    m.put(key, 1);
    System.out.println(m.size());
    key = null;
    System.gc();
    Thread.sleep(100);
    System.out.println(m.size());

System.gc は GC の実行を保証しませんが、私の Oracle の JVM 7 では常に実行され、このテストが出力されます。

1
0

これは、キーがマップ自体以外から参照されていないため、GC がマップからエントリを削除したことを意味します。

于 2013-12-23T12:04:06.963 に答える
1

ドキュメントは、このコードがあまり役に立たないことを意味します:

WeakHashMap<Integer, String> numbers = new WeakHashMap<Integer, String>();
numbers.put(new Integer(1), "one");
numbers.put(new Integer(2), "two");
System.out.println(numbers.get(new Integer(1))); // prints "one"
// let's say a garbage collection happens here
System.out.println(numbers.get(new Integer(1))); // prints "null"
System.out.println(numbers.get(new Integer(2))); // prints "null"

これは、異なるインスタンスが等しい可能性があるすべてのクラスで発生します。javadoc は、これが役に立たないことをまだ気付いていない場合に備えて警告しているだけです。

于 2013-12-23T11:59:41.410 に答える