六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 22|回复: 0

传奇的WeakHashMap

[复制链接]

升级  72%

8

主题

8

主题

8

主题

童生

Rank: 1

积分
36
 楼主| 发表于 2013-2-3 10:40:33 | 显示全部楼层 |阅读模式
在广大的Java界,关于WeakHashMap一直都存在这么个传说:


可是WeakHashMap是真的自动移除其条目吗?

 

今天因为闲来无事,所以想看看WeakHashMap是如何自动实现移除其内部不用的条目从而达到的自动释放内存的目的的。仔细的看了看JVM自带的源代码的实现,在WeakHashMap是主要通过expungeStaleEntries这个函数的来实现的。基本上只要对WeakHashMap的内容进行访问就会调用这个函数,从而达到清除其内部不在为外部引用的条目。但是如果预先生成了WeakHashMap,而在GC以前又不曾访问该WeakHashMap,那不是就不能释放内存了吗?

 

写个代码测试一把:


public static void main(String[] args) throws Exception {        List<WeakHashMap<byte[][], byte[][]>> maps = new ArrayList<WeakHashMap<byte[][], byte[][]>>();        for (int i = 0; i < 1000; i++) {          WeakHashMap<byte[][], byte[][]> d = new WeakHashMap<byte[][], byte[][]>();          d.put(new byte[1000][1000], new byte[1000][1000]);          maps.add(d);          System.gc();          System.err.println(i);          }    }  
 


由于Java默认内存是64M,所以再不改变内存参数的情况下,该测试跑不了几步循环就内存溢出了。果不其然,WeakHashMap这个时候并没有自动帮我们释放不用的内存。
 
再加个对会对map进行访问的测试试试:

public static void main(String[] args) throws Exception {            List<WeakHashMap<byte[][], byte[][]>> maps = new ArrayList<WeakHashMap<byte[][], byte[][]>>();            for (int i = 0; i < 1000; i++) {              WeakHashMap<byte[][], byte[][]> d = new WeakHashMap<byte[][], byte[][]>();              d.put(new byte[1000][1000], new byte[1000][1000]);              maps.add(d);              System.gc();              System.err.println(i);                for (int j = 0; j < i; j++) {                  System.err.println(j+  " size" + maps.get(j).size());              }          }      }   这下测试就顺利通过了。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表