0

1行目と2行目をコメントしないと、1行目でOutOfMemoryErrorが発生します。逆の場合、<Key、Value>はWeakReferenceでラップされているため、OutOfMemoryErrorは発生しません。しかし、3行目の出力がわかりません---- i : 3869 Size : 3870 maxSize : 3870

Javaドキュメントから:

ガベージコレクタはいつでもキーを破棄する可能性があるため、WeakHashMapは、不明なスレッドがサイレントにエントリを削除しているように動作する可能性があります。

このステートメントに基づくと、サイズは減少するはずですが、3行目の出力は継続的に増加しているようです。なぜそうなのか ?

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

public class WrongWeakHashMapSize {

private static Map map = new HashMap();

public static void main(String[] args) {
    for (int i = 0, maxSize = 0; i < 10000000L; ++i) {
        /*
         * Line 1 Causes java.lang.OutOfMemoryError: Java heap space Error.
         * After this line i : 244 Size : 490 maxSize : 490.
         */
        map.put(new LargeObject(i), new Integer(i)); // Line 1
        /* After Commenting Line 1 :---- 
         * Line 2 Does not Cause java.lang.OutOfMemoryError. Because of WeakReference class use.I think Line 3
         * is showing wrong Size of MAP. it printed
         * i : 3869 Size : 3870 maxSize : 3870 which seems almost impossible
         * because 3870 objects of LargeObject can not be exist at a time.
         */
        map.put(new WeakReference(new LargeObject(i)), new WeakReference(new Integer(i))); // Line 2
        maxSize = maxSize < map.size() ? map.size() : maxSize; // Line 3
        System.out.println("i : " + i + " Size : " + map.size() + " maxSize : " + maxSize); // Line 4
    }
}

public static class LargeObject {
    private final byte[] space = new byte[1024 * 1024];
    private final int id;

    public LargeObject(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }
}
}
4

3 に答える 3

3

これmap.size()は、マップ内のキーと値のペアの数が得られるためです。参照のガベージ コレクションはマップから参照を削除せずweak、オブジェクトをガベージするだけです。

willの唯一の効果は、WeakReference一部LargeObjectの およびIntegerが破棄の対象となることです。キーと値のマッピングは引き続きマップ内にあるため、引き続きカウントされます。

于 2013-03-22T09:56:06.410 に答える
0

サイズはマップ実装内の int フィールドであり、GC は WeakReference を削除した後にそれを減分しないため

詳細については、WeakHashMap#size() 実装を参照してください。WeakHashMap は、収集された WeakReferences のキューを格納し、必要に応じてサイズ サイズを再カウントします。

于 2013-03-22T09:54:48.307 に答える
0

ソース: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references 参照キュー

WeakReference が null を返し始めると、それが指すオブジェクトはガベージになり、WeakReference オブジェクトはほとんど役に立たなくなります。これは通常、何らかのクリーンアップが必要であることを意味します。たとえば、WeakHashMap は、死んだ WeakReferences の数が増え続けるのを避けるために、そのような無効なエントリを削除する必要があります。

ReferenceQueue クラスを使用すると、無効な参照を簡単に追跡できます。ReferenceQueue を弱参照のコンストラクターに渡すと、参照オブジェクトが指しているオブジェクトがガベージになると、参照オブジェクトは自動的に参照キューに挿入されます。その後、一定の間隔で ReferenceQueue を処理し、無効な参照に必要なクリーンアップを実行できます。

于 2013-03-22T10:22:23.243 に答える