试图弄清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
,您可能应该调用该方法以获得更准确的结果。