在Java中,虽然不须要程序员手动去管理对象的生命周期,可是若是但愿某些对象具有必定的生命周期的话(好比内存不足时JVM就会自动回收某些对象从而避免OutOfMemory的错误)就须要用到软引用和弱引用了。java
从Java SE2开始,就提供了四种类型的引用:强引用、软引用、弱引用和虚引用。Java中提供这四种引用类型主要有两个目的:第一是可让程序员经过代码的方式决定某些对象的生命周期;第二是有利于JVM进行垃圾回收。下面来阐述一下这四种类型引用的概念:android
引用分为四个,从高到低的级别以此为强引用-软引用-弱引用-虚引用.程序员
引用类型缓存
类别 | 回收机制 | 用途 | 生存时间 |
---|---|---|---|
强引用 | 从不回收 | 对象状态 | JVM中止运行时 |
软引用 | 内存不足时进行回收 | 缓存 | 内存不足 |
弱引用 | 对象不被引用时回收 | 缓存 | GC运行后 |
虚引用 | 对象被回收时 | 管理控制精确内存稳定性 | unknown |
强引用(Strong Reference)
永不回收。
强引用就是在程序代码之中广泛存在的,相似Object obj = new Object()
这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。网络
弱引用(Soft Reference)
重点回收对象。
弱引用也是用来描述非必需对象的,被弱引用关联的对象只能生存到下一次垃圾收集发生以前。框架
软引用(Weak Reference)
内存将要溢出时才被回收。
软引用是用来描述一些还有用但并不是必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常以前,将会把这些对象列表回收范围之中进行二次回收。若是此次回收尚未足够的内存,才会抛出内存溢出异常。异步
虚引用(了解)(Phantom Reference)
虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,彻底不会对其生存时间构成影响,也没法经过虚引用来取得一个对象实例。为一个对象设置虚引用关联的惟一目的就是能在这个对象被收集器回收时收到一个系统通知。ide
经常使用的弱引用和软引用ui
好比在图片加载框架中,经过弱引用来实现内存缓存。this
//实现图片异步加载的类 public class AsyncImageLoader { //以Url为键,SoftReference为值,创建缓存HashMap键值对。 private Map<String, SoftReference<Drawable>> mImageCache = new HashMap<String, SoftReference<Drawable>>(); //实现图片异步加载 public Drawable loadDrawable(final String imageUrl, final ImageCallback callback) { //查询缓存,查看当前须要下载的图片是否在缓存中 if(mImageCache.containsKey(imageUrl)) { SoftReference<Drawable> softReference = mImageCache.get(imageUrl); if (softReference.get() != null) { return softReference.get(); } } final Handler handler = new Handler() { @Override public void dispatchMessage(Message msg) { //回调ImageCallbackImpl中的imageLoad方法,在主线(UI线程)中执行。 callback.imageLoad((Drawable)msg.obj); } }; /*若缓存中没有,新开辟一个线程,用于进行从网络上下载图片, * 而后将获取到的Drawable发送到Handler中处理,经过回调实如今UI线程中显示获取的图片 */ new Thread() { public void run() { Drawable drawable = loadImageFromUrl(imageUrl); //将获得的图片存放到缓存中 mImageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); Message message = handler.obtainMessage(0, drawable); handler.sendMessage(message); }; }.start(); //若缓存中不存在,将从网上下载显示完成后,此处返回null; return null; } //定义一个回调接口 public interface ImageCallback { void imageLoad(Drawable drawable); } //经过Url从网上获取图片Drawable对象; protected Drawable loadImageFromUrl(String imageUrl) { try { return Drawable.createFromStream(new URL(imageUrl).openStream(),"debug"); } catch (Exception e) { // TODO: handle exception throw new RuntimeException(e); } } }
Handler 弱引用,防止内存泄漏
public class MainActivity extends AppCompatActivity { private Handler handler ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); handler = new MyHandler( this ) ; new Thread(new Runnable() { @Override public void run() { handler.sendEmptyMessage( 0 ) ; } }).start() ; } private static class MyHandler extends Handler { WeakReference<MainActivity> weakReference ; public MyHandler(MainActivity activity ){ weakReference = new WeakReference<MainActivity>( activity) ; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); if ( weakReference.get() != null ){ // update android ui } } } }