在学习Handler时,发现Handler容易引起内存泄漏,解决办法就是采用弱引用。通过学习,那就总结一下四种引用。
- 强引用
- 软引用
- 弱引用
- 虚引用
从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能够更加灵活的控制对象的生命周期。
这四种级别由高到低依次为:强引用、软引用、弱引用、虚引用。
强引用
我们使用的大部分引用实际上都都是强引用,例如:
Object obj = new Object();
当内存不足时,Java虚拟机宁愿跑出OutOfMemoryError的错误,使程序异常终止,也不会回收这些强引用的对象。
如果不想使用时,可以 obj = null; 来取消强引用,只有JVM会在合适的时间来回收该对象。
ArrayList中的clear()函数就是采用的这种方式来及时释放内存的,又避免了后续调用add()等函数添加元素导致的重新分配内存。
软引用
SoftReference
如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它。如果内存空间不够了,就会回收这些对象的引用。只要没有被回收,这些对象就可以正常使用。
String str = new String("abc");
SoftReference<String> soft = new SoftReference<String>(str);
实际应用,例如浏览器的回退按钮。
后退时,上一个网页是重新进行请求还是从缓存中拿出来?
如果一个网页在浏览结束后,被回收了,那么回退时,就需要进行重新请求和构建。
如果将浏览过的网页都存进内存中,又会很轻易的造成内存溢出。
此时就可以将所有浏览过的网页对象使用软引用,没被回收,直接拿来用。被回收了就重新构建。
弱引用
WeakReference
在垃圾回收器线程扫描内存区域过程中,一旦发现了只具有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存。
当要获得weak reference引用的object时, 首先需要判断它是否已经被回收。
weakCar.get();
获取的值为null,就说明该对象已经被回收了。
软引用和弱引用的区别:不管内存空间是否吃紧,只具有弱引用的对象都会被内存回收,只有内存空间不足,才会将只有软引用的对象回收。只有具有弱引用的对象拥有更短的生命周期,不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
进一步理解软引用和弱引用:
被软引用关联的对象只有在内存不足时才会被回收
被弱引用关联的对象在JVM进行垃圾回收时总会被回收
在使用软引用和弱引用的时候,我们可以显示地通过System.gc()来通知JVM进行垃圾回收,
但是要注意的是,虽然发出了通知,JVM不一定会立刻执行,也就是说这句是无法确保此时JVM一定会进行垃圾回收的。
[Android]Handler引起内存泄漏的原因以及解决办法
虚引用
“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。