2011-08-12 9 views
0

ConcurrentWeakKeyHashMapがメモリ状態/ガベージコレクションにどのように応答するかを理解しようとしています。ConcurrentWeakKeyHashMap size()メソッド

maxNum == 6000のJUnitテストのコードでは、 アサーションステートメントが失敗しました。サイズは= 4123(またはそれに類するもの)でした。

私はJVM -Xmxを500mに設定しましたが、6000を得ることを望んでいましたが、運はありません。

ガベージコレクションのためにサイズが変更されたと仮定すると、弱いキーはどのような条件で再利用されますか?すなわち、「低メモリ、低その他」状態?

int maxNum = 6000; 
    int initalCapacity = 2*maxNum; 
    ConcurrentMap<String,String> concurrentMap = new ConcurrentWeakKeyHashMap<String,String>(initalCapacity);  

    int count = 0; 
    for(int i=0; i<maxNum; i++) { 
     String key = "k" + i; 
     String value = "v" + i; 
     concurrentMap.put(key, value); 
     count = i; 
     //System.out.println(concurrentMap.size()); 
    } 

    int size = concurrentMap.size(); 
    assertEquals(size, maxNum); 
    System.gc(); 
    size = concurrentMap.size(); 
    assertEquals(size, maxNum); 

EDIT

強いオブジェクト内の弱い鍵を固定することによって、私はいつもは、6000/MAXNUMBERを取得。 即ち

// our strong object 
    List<String> strongList = new ArrayList(); 
    for(int i=0; i<maxNum; i++) { 
     String key = "k" + i; 
     String value = "v" + i; 
     concurrentMap.put(key, value); 

      // key is now pinned in strong object 
     strongList.add(key); 
    } 

    // size will now equal to maxNum, as nothing gets reclaimed 
    int size = concurrentMap.size(); 

答えて

3

オブジェクトへの「強い」参照がもはや存在する場合、弱参照を再利用しないます。

これはガベージコレクションのために発生します。ガベージコレクションは、バックグラウンドで(またはメモリが不足して)予期せず発生します。特に、利用可能なメモリがまだ十分にある場合でも(特に「若い人が死亡した」オブジェクトの場合、システムは早期にそれらを収集しようとします)、発生する可能性があります。

私は、ConcurrentWeakHashMap#sizeが常に完全に正確であるとは想定しません。それはより正確に得るためにあなたがおそらく呼び出すべき方法purgeStaleEntriesを持っています。

+0

私は実際にどのエントリが再生されるかを制御できないように見えます。 – portoalet

+0

はい、あなたは(*別の参照をどこかに置くことによって)*回収*できないものだけを制御できます。 – Thilo

+0

強いオブジェクト(ConcurrentHashMap)にキーを固定すると、私は6000を得ました。 Thiloありがとう。 – portoalet