强、软、弱、虚引用的区别

咕咚 于 2019-12-01 发布

强引用

StrongReference 强引用是最普遍的引用方式。JVM 执行垃圾回收时,只要是强引用,该引用占用的内存空间就不会释放。

软引用

SoftReference 如果一个对象为软引用,那么在 JVM 内存足够的情况下,GC 将不会回收它,一旦内存不足,垃圾回收器就会将它们的内存回收。示例:

SoftReference<String> sr = new SoftReference(new String("123"));
String num = sr.get();// num 可能为空,使用时需要判空

弱引用

WeakReference 如果一个对象为弱引用,当垃圾回收线程在扫描内存区域时,发现了它,便会对它进行回收,不论当前内存是否足够。

由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

软引用跟弱引用都都可以跟一个引用队列 ReferenceQueue 联合使用,如果它们为回收,JVM 将会把他们放入指定的引用队列中。

WeakReference<String> wr = new WeakReference(new String("123"));
String num = wr.get();// num 可能为空

虚引用

PhantomReference 形同虚设,它无法决定对象的生命周期,如果一个对象持有虚引用,那么它跟没有持有引用一样,在任何时候都可能被垃圾回收。

虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 ReferenceQueue 联合使用。

总结

android 开发的多数场景使用弱引用来解决内存泄漏问题,标记为软引用的对象可以在内存不足是被回收,而弱引用在执行 GC 时就会被回收,很及时,如果有内存泄漏风险的对象使用了软引用,那么它存活的周期还是比较长的,并不能很好的达到避免内存泄漏的目的的。

软引用适合用来实现内存敏感的高速缓存。比如 Bitmap 缓存,或者在浏览器中前进后退页面缓存。

软引用 VS 弱引用

具体以上四种区别如下表格所示: 通过表格来说明一下,如下:

引用类型 被垃圾回收时间 用途 生存时间
强引用 从来不会 对象的一般状态 JVM停止运行时终止
软引用 当内存不足时 对象缓存 内存不足时终止
弱引用 正常垃圾回收时 对象缓存 垃圾回收后终止
虚引用 正常垃圾回收时 跟踪对象的垃圾回收 垃圾回收后终止

参考链接