WeakHashMap的使用不慎导致内存溢出的问题的分析
来源:优易学  2011-11-22 10:54:48   【优易学:中国教育考试门户网】   资料下载   IT书店
  目前社区中有几个应用使用了类似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
  }
  }
  }
  }

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训