看Java核心技术1的时候看到HashMap的对象,书中讲到:
1.如果有一个值,对应的键不再使用他了,但由于key与value之间存在强引用,是不会被垃圾回收的
2.垃圾回收器跟踪活动的对象,只要映射对象是活动的,其中的所有桶也是活动的,它们不能被回收
所以做了下面的测试:
publicclass TestJava {publicstaticvoid 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对象还存在"; @Overridepublic String toString() {return strTest; } @Overrideprotectedvoid 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