Java中的引用一共有四種:強引用、軟引用瘦馍、弱引用 和 虛引用歼秽。下面來分別說一下這四種引用的用法及區(qū)別。
強引用(StrongReference)
是指創(chuàng)建一個對象并把這個對象賦給一個引用變量情组。
比如:
String str ="StrongReference";
/**
* 強引用(StrongReference)
* 只要某個對象有強引用與之關(guān)聯(lián)燥筷,JVM必定不會回收這個對象,
* 即使在內(nèi)存不足的情況下院崇,JVM寧愿拋出OutOfMemory錯誤也不會回收這種對象
*
*/
public static void funStrongReference() {
String str="StrongReference";
}
軟引用(SoftReference)
如果一個對象具有軟引用肆氓,內(nèi)存空間足夠,垃圾回收器就不會回收它底瓣;
如果內(nèi)存空間不足了谢揪,就會回收這些對象的內(nèi)存。只要垃圾回收器沒有回收它捐凭,該對象就可以被程序使用拨扶。
在Android中,軟引用可用來實現(xiàn)內(nèi)存敏感的高速緩存,比如網(wǎng)頁緩存茁肠、圖片緩存等患民。使用軟引用能防止內(nèi)存泄露,增強程序的健壯性垦梆。
SoftReference的特點是它的一個實例保存對一個Java對象的軟引用匹颤, 該軟引用的存在不妨礙垃圾收集線程對該Java對象的回收。
/**
* 軟引用(SoftReference)
* 對于軟引用關(guān)聯(lián)著的對象奶赔,只有在內(nèi)存不足的時候JVM才會回收該對象
*
*
*/
public static void funSoftReference() {
SoftReference<String> str = new SoftReference<String>(new String("funSoftReference"));
System.out.println(str.get());
//通知JVM進行內(nèi)存回收
System.gc();
System.out.println(str.get());
}
運行代碼
public static void main(String[] args) {
funSoftReference();
// funWeakReference();
// funPhantomReference();
}
運行后得到結(jié)果:弱引用(WeakReference)
弱引用也是用來描述非必需對象的惋嚎,當JVM進行垃圾回收時,無論內(nèi)存是否充足站刑,都會回收被弱引用關(guān)聯(lián)的對象另伍。
在Android中,常常使用弱引用來解決內(nèi)存泄漏的問題,例如handler持有了一個Activity的引用摆尝,當這個Activity退出時消息隊列中還有未處理的消息或者正在處理消息温艇,而消息隊列中的Message持有mHandler實例的引用,mHandler又持有Activity的引用堕汞,所以導致該Activity的內(nèi)存資源無法及時回收勺爱,引發(fā)內(nèi)存泄漏。解決辦法是讓handler持有一個activity的弱引用讯检。
/**
* 弱引用(WeakReference)
* 當JVM進行垃圾回收時琐鲁,無論內(nèi)存是否充足,都會回收被弱引用關(guān)聯(lián)的對象人灼。
* eg:在Android中围段,存在內(nèi)存泄漏
*
*/
public static void funWeakReference() {
WeakReference<String> str = new WeakReference<String>(new String("funWeakReference"));
System.out.println(str.get());
//通知JVM進行內(nèi)存回收
System.gc();
System.out.println(str.get());
}
運行代碼:
public static void main(String[] args) {
// funSoftReference();
funWeakReference();
// funPhantomReference();
}
得到結(jié)果:
虛引用(PhantomReference)
虛引用和前面的軟引用、弱引用不同投放,它并不影響對象的生命周期奈泪。在java中用java.lang.ref.PhantomReference類表示。如果一個對象與虛引用關(guān)聯(lián)灸芳,則跟沒有引用與之關(guān)聯(lián)一樣涝桅,在任何時候都可能被垃圾回收器回收。
要注意的是烙样,虛引用必須和引用隊列關(guān)聯(lián)使用冯遂,當垃圾回收器準備回收一個對象時,如果發(fā)現(xiàn)它還有虛引用误阻,就會把這個虛引用加入到與之 關(guān)聯(lián)的引用隊列中债蜜。程序可以通過判斷引用隊列中是否已經(jīng)加入了虛引用,來了解被引用的對象是否將要被垃圾回收究反。如果程序發(fā)現(xiàn)某個虛引用已經(jīng)被加入到引用隊列寻定,那么就可以在所引用的對象的內(nèi)存被回收之前采取必要的行動。
/**
* 虛引用(PhantomReference)
* 只要某個對象有強引用與之關(guān)聯(lián)精耐,JVM必定不會回收這個對象狼速,
* 即使在內(nèi)存不足的情況下,JVM寧愿拋出OutOfMemory錯誤也不會回收這種對象
*
*/
public static void funPhantomReference() {
ReferenceQueue<String> queue = new ReferenceQueue<>();
PhantomReference<String> str = new PhantomReference<String>("funPhantomReference", queue);
System.out.println(str.get());
}
運行代碼:
public static void main(String[] args) {
// funSoftReference();
// funWeakReference();
funPhantomReference();
}
得到結(jié)果: