看Java核心技术1的时候看到HashMap的对象,书中讲到:
1.如果有一个值,对应的键不再使用他了,但由于key与value之间存在强引用,是不会被垃圾回收的
2.垃圾回收器跟踪活动的对象,只要映射对象是活动的,其中的所有桶也是活动的,它们不能被回收
所以做了下面的测试:
public class TestJava { public static void main(String[] args) { HashMap map = new HashMap(); Test t1 = new Test(); Test t2 = new Test(); map.put(t1, "1"); map.put(t2, "2"); t1 = null; System.gc(); System.out.println("第1步" + map); t2 = null; System.gc(); System.out.println("第2步" + map); map.clear(); System.gc(); System.out.println("第3步" + map); } } class Test { private String strTest = "该Test对象还存在"; @Override public String toString() { return strTest; } @Override protected void finalize() throws Throwable { // TODO Auto-generated method stub System.out.println("该Test对象被释放了"); } }
测试结果:
果然,GC不会回收这两个垃圾,这个跟Java中的HashMap默认是强引用有关的
分析:
原因:其实HashMap存进去的是t1跟t2指向的地址(堆内存中两条黑色的线)作为key,但进行t1=null,t2=null的时候,本来按照常理来说,Java回收机制会对那些没有引用的堆内存对象进行回收,但不幸的是,HashMap依旧会强引用着t1跟t2的堆内存对象,导致GC无法对其进行回收
https://blog.csdn.net/simplebam/article/details/74135502