java语言中为对象的引用分为了四个级别,分别为 强引用 、软引用、弱引用、虚引用。java
本文只针对java中的弱引用进行一些分析,若有出入还请多指正。函数
在分析弱引用以前,先阐述一个概念:什么是对象可到达和对象不可到达状态。spa
其实很简单,我举个例子:orm
如今有以下两个类class A class B,在JVM上生成他们两个类的实例分别为 instance a instance b对象
有以下表达式:内存
A a = new A();it
B b = new B();class
两个强引用对象就生成了,好吧,那么这个时候我作一下修改:内存泄漏
A a = new A();构造函数
B b = new B(a);
B的默认构造函数上是须要一个A的实例做为参数的,那么这个时候 A和B就产生了依赖,也能够说a和b产生了依赖,咱们再用一个接近内存结构的图来表达:
a是对象A的引用,b是对象B的引用,对象B同时还依赖对象A,那么这个时候咱们认为从对象B是能够到达对象A的。
因而我又修改了一下代码
A a = new A();
B b = new B(a);
a = null;
A对象的引用a置空了,a再也不指向对象A的地址,咱们都知道当一个对象再也不被其余对象引用的时候,是会被GC回收的,很显然及时a=null,那么A对象也是不可能被回收的,由于B依然依赖与A,在这个时候,形成了内存泄漏!
那么如何避免上面的例子中内存泄漏呢?
很简单:
A a = new A();
B b = new B(a);
a = null;
b = null;
这个时候B对象再也没有被任何引用,A对象只被B对象引用,尽管这样,GC也是能够同时回收他们俩的,由于他们处于不可到达区域。
弱引用来了!
A a = new A();
WeakReference wr = new WeakReference(a);
//B b = new B(a);
当 a=null ,这个时候A只被弱引用依赖,那么GC会马上回收A这个对象,这就是弱引用的好处!他能够在你对对象结构和拓扑不是很清晰的状况下,帮助你合理的释放对象,形成没必要要的内存泄漏!!