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

发表于   |   --

强引用

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停止运行时终止
软引用 当内存不足时 对象缓存 内存不足时终止
弱引用 正常垃圾回收时 对象缓存 垃圾回收后终止
虚引用 正常垃圾回收时 跟踪对象的垃圾回收 垃圾回收后终止

参考链接

rss facebook jianshu juejin weibo twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora