SoftReference的使用

来源:互联网 发布:linux apache ant安装 编辑:程序博客网 时间:2024/05/22 12:45

一、softReference的作用

       SoftReference的主要特点就是在当内存不够的时候,GC会回收SoftReference所引用的对象。所以,在memory sensitive的项目中将某些数据设置成SoftReference可以避免内存的溢出。

1、创建一个SoftReference

SoftReference<Map<String, String>> softReference = new SoftReference<Map<String, String>>(new HashMap<String, String>());

2、使用softReference

Map<String, String> map = softReference.get();if (map == null) {    softReference = new SoftReference<Map<String, String>>(        map = new HashMap<String, String>());}

3、因为是SoftReference,有可能已经被GC回收了,所以需要判断softReference.get()的返回值是否为null。如果是的话,就再重新new一个。注意这里的map赋值代码,如果写成这样:

Map<String, String> map = softReference.get();if (map == null) {    softReference = new SoftReference<Map<String, String>>(        new HashMap<String, String>());}map = softReference.get();
GC有可能发生在softReference = new SoftReference<Map<String, String>>(new HashMap<String, String>())和map = softReference.get();之间,那么map仍然有可能为null,虽然这种几率小到几乎不存在。

4、SoftReference设计对象Cache

   SoftReference是强引用,它保存的对象实例,除非JVM即将OutOfMemory,否则不会被GC回收。这个特性使得它特别适合设计对象Cache。对于Cache,我们希望被缓存的对象最好始终常驻内存,但是如果JVM内存吃紧,为了不发生OutOfMemoryError导致系统崩溃,必要的时候也允许JVM回收Cache的内存,待后续合适的时机再把数据重新Load到Cache中。这样可以系统设计得更具弹性。

实例:

软引用在设备内存比较少的时候特别有用,比如Android系统。

  一个android应用如果设计到通过网络获取图片,为了让系统更快的运行和更节省流量我们可以将已经下载下来的图片缓存起来,当第二次浏览到该图片时就可以从缓存中拿。

  缓存的方式有:一是放在系统内存中这样效率最高,二是把文件写到外部存储器上。但是就目前而言android系统的内存是非常的有限的不可能像PC机那样配置那么高的内存,而且外部存储器的容量也是有限的。

public class ImageLoader {            private Map<String,SoftReference<Bitmap>> cacheImage = new HashMap<String,SoftReference<Bitmap>>();            public void loadImage(final String path,final Callback callback){          SoftReference<Bitmap> softReference = cacheImage.get(path);          if(softReference!=null){              Bitmap bm = softReference.get();              if(bm!=null){                  callback.execute(bm);                  return;              }          }          new Thread(new Runnable() {             public void run() {              HttpClient client = new DefaultHttpClient();              try {                  HttpResponse response = client.execute(new HttpGet(path));                  HttpEntity entity = response.getEntity();                  byte []bs= EntityUtils.toByteArray(entity);                  final Bitmap bm = BitmapFactory.decodeByteArray(bs, 0,bs.length);                  SoftReference<Bitmap> reference = new SoftReference<Bitmap>(bm);                   cacheImage.put(path,reference);                  callback.execute(bm);                  entity.consumeContent();              } catch (Exception e) {                  e.printStackTrace();              }              }          }).start();      }            public static abstract class Callback{          abstract void execute(Bitmap bm);      }  }  

注:

WeakReference是弱引用,其中保存的对象实例可以被GC回收掉。这个类通常用于在某处保存对象引用,而又不干扰该对象被GC回收,通常用于Debug、内存监视工具等程序中。因为这类程序一般要求即要观察到对象,又不能影响该对象正常的GC过程。

最近在JDK的Proxy类的实现代码中也发现了Weakrefrence的应用,Proxy会把动态生成的Class实例暂存于一个由Weakrefrence构成的Map中作为Cache。






原创粉丝点击