这可能是预期的行为,但我找不到任何说明的文档.我正在使用番石榴14.0.1.在下面的示例中,地图中没有对该键的强引用的条目将被删除,这是我所期望的,但是地图的大小不同步.
在第一次检查中,大小和计数都是5.但是,在第二次检查中,大小报告为5,但计数为0.为什么第二次检查报告地图大小为5时实际上没有地图中的条目?
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class MapSizeCheck {
public static void main(String[] args) {
keepReferencesAndCheckSize();
System.out.println();
discardReferencesAndCheckSize();
}
private static void keepReferencesAndCheckSize() {
Map<Object,Object> map = new MapMaker().weakKeys().makeMap();
List<Object> refs = Lists.newArrayList();
for(int i=0;i<5;i++) {
Object key = new Object();
Object value = new Object();
map.put(key, value);
refs.add(key); // Hold a strong reference to the key.
}
System.gc();
int size = map.size();
int count = 0;
Iterator<Object> it = map.keySet().iterator();
while(it.hasNext()) {
count++;
it.next();
}
System.out.println("Size : " + size);
System.out.println("Count : " + count);
}
private static void discardReferencesAndCheckSize() {
Map<Object,Object> map = new MapMaker().weakKeys().makeMap();
for(int i=0;i<5;i++) {
Object key = new Object();
Object value = new Object();
map.put(key, value);
}
System.gc();
int size = map.size();
int count = 0;
Iterator<Object> it = map.keySet().iterator();
while(it.hasNext()) {
count++;
it.next();
}
System.out.println("Size : " + size);
System.out.println("Count : " + count);
}
}
Run Code Online (Sandbox Code Playgroud)
这是预期的行为,但在MapMaker文档中并没有像它那样明确.然而,它与CacheBuilder文档一致:
如果请求weakKeys,weakValues或softValues,则垃圾收集器可以回收缓存中存在的密钥或值.具有回收键或值的条目可以在每次高速缓存修改,偶尔的高速缓存访问或对Cache.cleanUp()的调用时从高速缓存中删除; 这些条目可以在Cache.size()中计算,但对于读取或写入操作永远不可见.
......以及JDK自己的WeakHashMap:
public int size()返回此映射中键 - 值映射的数量.此结果是快照,可能无法反映在下次尝试访问之前将被删除的未处理条目,因为它们不再被引用.
| 归档时间: |
|
| 查看次数: |
200 次 |
| 最近记录: |