您的位置:首页 > 移动开发 > Android开发

Android WeakReference与SoftReference

2014-09-15 11:01 162 查看
写这个文章就是看公司代码的时候,看到一个图片缓存的机制引发的。以前记得做图片缓存机制的时候,用到了SoftReference这个东东,但今天看我们公司之前的一个成熟的产品用的是LruCache类缓存,并且引入了WeakReference记住imageview。今天就来介绍下相关的内容。

WeakReference与SoftReference都可以用来保存对象的实例引用,这两个类与垃圾回收有关。

SoftReference:软引用。如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。这个特性使得它特别适合设计对象Cache。对于Cache,我们希望被缓存的对象最好始终常驻内存,但是如果JVM内存吃紧,为了不发生OutOfMemoryError导致系统崩溃,必要的时候也允许JVM回收Cache的内存,待后续合适的时机再把数据重新Load到Cache中。这样可以系统设计得更具弹性。但是补充一点,由于Android
2.3版本以后对SoftReference类引用的对象调整了回收策略,所以该类中的软引用缓存实际上没什么效果,可以去掉。可以使用Android提供的LruCache类。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

软引用可以更好地管理内存,稳定系统,防止oom的出现。但因使用软引用的对象初始化对象较为耗时,或者对象的状态在程序运行的时候发生变化,都会给重建对象和初始化造成麻烦,所以要合适选择,巧妙运用。

WeakReference:弱引用。保存的对象实例可以被GC回收掉。这个类通常用于在某处保存对象引用,而又不干扰该对象被GC回收。它与软引用的区别在于只具有弱引用的对象拥有更短暂的生命周期。可以用来优化内存,防止内存泄露,我们可以用来回收那些比较大内存但又不经常用的对象。

WeakReference应用场景:

(1)在缓存问题中,如果使用强引用,那么我们缓存的对象就会一直滞留在内存中,不会被回收,除非我们手动的将其从缓存中移除。此外,这还需要我们决定何时从缓存中移除对象,又一个手动管理内存的问题!此时,WeakReference就显示出它的价值了,例如WeakHashMap来存储bitmap的引用。

(2)有时我们会碰到一些不能继承的类,如final
class,无法继承它。假如我们要使用一个Widget类,因为某种缘故无法继承该类来加入某个功能。但是,我们必须将每个Widget对象和某个序列号关联,这时该怎么做呢?如果你想到了用numberMap.put(widget, widgetNumber)这个问题解决了,但是有可能会造成内存泄露;当我们不再需要某个Widget的number信息,此时应该从HashMap中将这个Entry移除,如果我们没手动移除,这个对象永远不会被垃圾回收器回收,这就造成了内存泄漏!解决这个问题最简单的方法是使用WeakHashMap,它的使用和普通的HashMap完全一样,不同点在于,WeakHashMap的key被实现为一种WeakReference(注意,是key

而不是value),当key对象被回收后,WeakHashMap会自动将对应的entry移除。比如异步加载图片需要把加载完成后的图片,用imageview显示,就可以获得view的弱引用。

再来啰嗦下java其他引用:

StrongReference:强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

PhantomReference: 虚引用,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有

虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息