一、概述
衆所周知,Java 中是由 JVM 負責內存的分配和回收,它的優點是使用方便,程序員不用再像使用 C 那樣操心內存,但同時也是它的缺點,不夠靈活。爲了解決內存操作不靈活這個問題,可以弱採用引用等方法。
在 JDK1.2 以前的版本中,當一個對象不被任何變量引用,那麼程序就無法再使用這個對象。也就是說,只有對象處於可觸及狀態,程序才能使用它。這就像在日常生活中,從商店購買了某樣物品後,如果有用,就一直保留它,否則就把它扔到垃圾箱,由清潔工人收走。
但有時候情況並不這麼簡單,你可能會遇到類似雞肋一樣的物品,食之無味,棄之可惜。這種物品現在已經無用了,保留它會佔空間,但是立刻扔掉它也不划算,因爲也許將來還會派用場。對於這樣的可有可無的物品,一種折衷的處理辦法是:如果家裏空間足夠,就先把它保留在家裏,如果家裏空間不夠,即使把家裏所有的垃圾清除,還是無法容納那些必不可少的生活用品,那麼再扔掉這些可有可無的物品。從JDK1.2 版本開始便有了對象的引用的機制,從而使程序能更加靈活的控制對象的生命週期。以下我們就詳細說明強引用和弱引用。
二、具體描述
1、強引用(StrongReference)
它類似於必不可少的生活用品,垃圾回收器絕不會回收它。當內存空間不足,Java 虛 擬機寧願拋出 OutOfMemoryError 錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足問題。強引用是使用最普遍的引用,以前我們使用的大部分引用實際 上都是強引用。例如:
Student student=new Student();
只要此引用存在沒要被釋放(沒有使 student =null),垃圾回收器永遠不會回收。只有當這個引用被釋放之後,垃圾回收器纔可能回收,這也是我們經常所用到的編碼形式。
2、弱引用(WeakReference)
如果一個對象只具有弱引用,那就類似於可有可物的生活用品。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存,(不過,由於垃圾回收器是一個優先級很低的線程,因此不一定 會馬上發現那些只具有弱引用的對象)。如:
只要student還指向Student就不會被回收
Student student=new Student();
WeakReference<Student> weakStudent=new WeakReference<Student>(student);
當要獲得 weak reference 引用的 student 時,可以使用:
weakStudent.get();
如果此方法返回的爲空,那麼說明 weakStudent 指向的對象 student 已經被回收了。 例如我們常用的在內部類的 Handler 中使用的 Activity 弱引用,防止內存泄漏:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CountdownTimeHandler handler = new CountdownTimeHandler(this);
}
public static class CountdownTimeHandler extends Handler {
final WeakReference<MainActivity> mWeakReference;
public CountdownTimeHandler(MainActivity activity) {
mWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if( mWeakReference.get() != null ){
//更新UI
}
}
}
}