试图弄清ConcurrentWeakKeyHashMap如何响应内存条件/垃圾回收。

在我的JUnit测试中,以下代码的maxNum == 6000,
assert语句失败,大小== 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);


编辑

通过将弱键固定在强对象上,我总是得到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();

最佳答案

当不再有对对象的“强”引用时,弱引用将被回收。

发生这种情况的原因是垃圾回收,而垃圾回收又在后台(或内存不足时)发生了不可预测的事情。特别是,即使仍然有足够的可用内存,也可能发生这种情况(尤其是对于“早逝”的对象,系统会尝试尽早收集这些内存)。

我也不认为ConcurrentWeakHashMap#size一直都是完全准确的。它具有方法purgeStaleEntries,您可能应该调用该方法以获得更准确的结果。

07-26 02:07