在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 } } } }