现在的位置: 首页 > 综合 > 正文

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

2013年12月16日 ⁄ 综合 ⁄ 共 1269字 ⁄ 字号 评论关闭
对WeakHashMap的使用不慎导致内存溢出分析:
 
目前社区中有几个应用使用了类似Locker的代码,基本上都是从消息系统引擎中提取出来的,唯
一的区别在于消息中使用的Locker中的id的类型为long,而id在作为键被put进Map时被JVM自动转换成了Long,因此避免了
WeakHashMap中的键被值所引用。而如果使用String作为id则会因为Map中的值引用了自己的键,导致JVM无法根据键是否还被引用而清除
WeakHashMap中的entry。可通过下面的测试代码,清楚的观察到结果。
 

public class Locker {
    private static WeakHashMap<String, Locker> lockerMap = new WeakHashMap<String, Locker>();
    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
            }
        }
    }
}

抱歉!评论已关闭.