HashMap内存泄漏
在看
ThreadLocal
源码的时候,其中内部类
ThreadLocalMap
的存储数据结构的内部类
Entry
继承了
WeakReferenc
,为了能够搞清楚这个
ThreadLocal
,就只能先学习一下
WeakReferenc
了。在了解了
WeakReferenc
之后,又想到能不能使用强引用呢?,好吧又学习了一波在
Map
中使用强引用的弊端。(好吧,有时候为了学习一个东西,不得不又去了解其他的一下内容,好家伙简直俄罗斯套娃)
言归正传,下面就来了解一下HashMap
存在内存泄漏的原因。直接上代码
public class TestJava {
public static void main(String[] args) {
Map<MyClass, String> map = new HashMap<MyClass, String>();
MyClass my1 = new MyClass();
MyClass my2 = new MyClass();
map.put(my1, "my1");
map.put(my2, "my2");
my1 = null;
System.gc();
System.out.println("第1步" + map);
my2 = null;
System.gc();
System.out.println("第2步" + map);
map.clear();
System.gc();
System.out.println("第3步" + map);
}
}
class MyClass {
private String msg = super.toString() + " 对象还在呢";
@Override
public String toString() {
return msg;
}
@Override
protected void finalize() throws Throwable {
System.out.println(super.toString() + " 对象被释放了");
}
}
运行结果如下:
果然,在my1
和my2
设置null
之后GC
没有回收这两个垃圾,这个跟Java
中的HashMap
默认是强引用是有关的
原因:其实HashMap
存进去的是my1
跟my2
指向的地址(堆内存中两条红色的线)作为key
,但进行my1=null
,my2=null
的时候,本来按照常理来说,Java
回收机制会对那些没有引用的堆内存对象进行回收,但不幸的是,HashMap
依旧会强引用着my1
跟my2
的堆内存对象,导致GC
无法对其进行回收。