三九宝宝网宝宝教育学龄段教育

WeakHashMap的使用不慎导致内存溢出分析

11月21日 编辑 39baobao.com

[宝贝交友不慎父母需淡定指导]没有哪位父母,忍心并甘心看到自己努力培养的孩子被他的“坏”朋友而带消极影响。但是,同样不能否认的是,孩子在成长过程当中,会遇到形形色色的朋友。那么显然,孩子与谁交往、与谁...+阅读

目前社区中有几个应用使用了类似Locker的代码,基本上都是从消息系统引擎中提取出来的,的区别在于消息中使用的Locker中的id的类型为long,而id在作为键被put进Map时被JVM自动转换成了Long,因此避免了 WeakHashMap中的键被值所引用。而如果使用String作为id则会因为Map中的值引用了自己的键,导致JVM无法根据键是否还被引用而清除 WeakHashMap中的entry。可通过下面的测试代码,清楚的观察到结果。

public class Locker {

private static WeakHashMaplockerMap = new WeakHashMap();

private final String id;

private Locker(String id) {

this.id= id;

}

public synchronized static Locker acquire(String id) {

Locker locker = lockerMap.get(key);

if (locker == null) {

locker = new Locker(id);

lockerMap.put(id, locker); 问题代码,导致了entry.key == entry.value.id

lockerMap.put(new String(id), locker); 这是一种修改方式,保证了WeakHashMap中的key,没有被value直接或间接所引用

}

return locker;

}

public String getId() {

return this.id;

}

public static int getSize() {

return lockerMap.size();

}

}

public class LockerTest extends TestCase {

public void testLocker() {

for (int i = 0; i< 10000000; i++) {

Locker.acquire("abc" + i);

if (i % 10000 == 0) {

System.gc();

System.out.println(Locker.getSize()); 输出垃圾回收后的Map的Size

}

}

}

}

推荐阅读
图文推荐