强引用
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 弱引用
- 软引用在内存不足时才会回收,而弱引用,只要 GC 开始扫描,它就会被回收。
- 虚引用日常几乎没用到。
具体以上四种区别如下表格所示: 通过表格来说明一下,如下:
引用类型 | 被垃圾回收时间 | 用途 | 生存时间 |
---|---|---|---|
强引用 | 从来不会 | 对象的一般状态 | JVM停止运行时终止 |
软引用 | 当内存不足时 | 对象缓存 | 内存不足时终止 |
弱引用 | 正常垃圾回收时 | 对象缓存 | 垃圾回收后终止 |
虚引用 | 正常垃圾回收时 | 跟踪对象的垃圾回收 | 垃圾回收后终止 |