1. 程式人生 > >Java中四種引用 強 軟 弱 虛

Java中四種引用 強 軟 弱 虛

前言

面試題:Java中的軟引用,弱引用在Android 是哪個的使用


目錄

  • 一:哪四種引用
  • 二:區別在哪
  • 三:在Android中的使用場景
      1. Handler 弱引用,防止記憶體洩漏
      1. Bitmap軟引用防止OOM
  • 參考

一:哪四種引用

  • 強引用(Strong Reference)
  • 軟引用(Soft Reference)
  • 弱引用(WeakReference)
  • 虛引用

二:區別在哪

1. 強引用(Strong Reference)

強引用是指在程式程式碼中普遍存在的,類似“Object obj=new Object()”這類的引用,只要強引用還存在,垃圾收集器永遠不會回收掉被引用的物件。

只要某個物件有強引用與之關聯,JVM必定不會回收這個物件,即使在記憶體不足的情況下,JVM寧願丟擲OutOfMemory錯誤也不會回收這種物件

2. 軟引用(Soft Reference)

軟引用是用來描述一些有用但並不是必需的物件。對於軟引用關聯著的物件,只有在記憶體不足的時候JVM才會回收該物件。因此,這一點可以很好地用來解決OOM的問題,並且這個特性很適合用來實現快取:比如網頁快取、圖片快取等。JDK 1.2之後,提供了SoftReference類來實現軟引用。

import java.lang.ref.SoftReference;
 
public class Main {
    public static void main(String[] args) {
         
        SoftReference<String> sr = new SoftReference<String>(new String("hello"));
        System.out.println(sr.get());
    }
}

3.弱引用(WeakReference)

弱引用也是用來描述非必需物件的,當JVM進行垃圾回收時,無論記憶體是否充足,都會回收被弱引用關聯的物件

import java.lang.ref.WeakReference;
 
public class Main {
    public static void main(String[] args) {
     
        WeakReference<String> sr = new WeakReference<String>(new String("hello"));
         
        System.out.println(sr.get());
        System.gc();                //通知JVM的gc進行垃圾回收
        System.out.println(sr.get());
    }
}

輸出結果

hello
null

4.虛引用(PhantomReference)

虛引用和前面的軟引用、弱引用不同,它並不影響物件的生命週期。在java中用java.lang.ref.PhantomReference類表示。如果一個物件與虛引用關聯,則跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收。

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
 
 
public class Main {
    public static void main(String[] args) {
        ReferenceQueue<String> queue = new ReferenceQueue<String>();
        PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
        System.out.println(pr.get());
    }
}

總結

對比 強引用 軟引用 弱引用 虛引用
引用強度 最強 第二 第三 最弱
如何使用 new Object() SoftReference WeakReference PhantomReference

三:在Android中的使用場景

1. Handler 弱引用,防止記憶體洩漏

 
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import java.lang.ref.WeakReference;
 
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
            }
        }
    }
 
}

2. Bitmap軟引用防止OOM

下面這段程式碼是摘自部落格:

http://blog.csdn.net/arui319/article/details/8489451

private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();
<br>....
public void addBitmapToCache(String path) {
// 強引用的Bitmap物件
Bitmap bitmap = BitmapFactory.decodeFile(path);
// 軟引用的Bitmap物件
SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);
// 新增該物件到Map中使其快取
imageCache.put(path, softBitmap);
}
public Bitmap getBitmapByPath(String path) {
// 從快取中取軟引用的Bitmap物件
SoftReference<Bitmap> softBitmap = imageCache.get(path);
// 判斷是否存在軟引用
if (softBitmap == null) {
return null;
}
// 取出Bitmap物件,如果由於記憶體不足Bitmap被回收,將取得空
Bitmap bitmap = softBitmap.get();
return bitmap;
}