Java中四種引用 強 軟 弱 虛
阿新 • • 發佈:2019-01-07
前言
面試題:Java中的軟引用,弱引用在Android 是哪個的使用
目錄
- 一:哪四種引用
- 二:區別在哪
- 三:在Android中的使用場景
-
- Handler 弱引用,防止記憶體洩漏
-
- 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;
}