所谓的强引用,软引用,弱引用,虚引用
其实是几种不同的对象创建方式,相当于给创建出来的对象打上不同的标签。
我们都知道对象的生命周期由垃圾收集器做GC来控制,我们虽然无法控制垃圾回收,但是我们能配合垃圾回收的规则,通过编码来管理某些对象的生命周期,更充分利用内存,减少无效对象的内存占用,避免OOM,这就可以用上强引用,软引用,弱引用,虚引用几种方式。
(1)强引用
Object o = new Object();
String a = new String(“hello world”);
在一个方法中使用以上两种创建方式,变量 o和 a 就保持着对Object 和 String的强引用,那么在栈帧中的局部变量表中可以通过动态链接直接找到堆中的Object 和 String 对象,堆中被强引用指向的对象,是不会被GC回收的。所以如果某些静态变量创建出来的强引用,就会一直得不到回收,导致内存泄漏或者内存溢出。
(2)软引用
Zoo zoo = new Zoo();
SoftReference<Zoo> zooSoft = new SoftReference<Zoo>(zoo);
软引用主要创建有用但非必需对象,当内存不足快导致OOM的时候才回收该对象。内存充足时候可以作为一些可有可无的缓存使用(热点数据缓存不能用!)。内存不足自动回收,这样保证了充分利用内存。
(3)弱引用
Zoo zoo = new Zoo();
WeakReference<Zoo> zooWeak = new WeakReference<Zoo>(zoo);
每次垃圾回收,都会回收弱引用的内存,zooWeak.get如果为null,说明zooWeak指向的对象被回收掉了。作用的话,可以DIY是做生命周期更短,访问更少的缓存。
(4)虚引用
Zoo zoo = new Zoo();
ReferenceQueue<Zoo> queue = new ReferenceQueue<Zoo>();
PhantomReference<Zoo> zooPhantom = new PhantomReference<Zoo>(zoo, queue);
虚引用基本上是一创建就会被回收,任何时候都可能被回收
给一个对象创建虚引用的时候,必须创建引用队列ReferenceQueue,在虚引用对象被回收时,会将虚引用对象加入引用队列,方便应用程序通过引用队列跟踪虚引用对象的回收情况(例如通过Unsafe类申请堆外内存的时候)。