Java引用方式包括:
強(qiáng)引用、軟引用、虛引用、弱引用
java的對(duì)象位于heap中,heap中的對(duì)象有強(qiáng)可及對(duì)象,軟可及對(duì)象、弱可及對(duì)象、虛可及對(duì)象及不可達(dá)對(duì)象。
強(qiáng)弱順序?yàn)椋簭?qiáng)、軟、弱、虛, 對(duì)于對(duì)象屬于那種可及對(duì)象,由他最強(qiáng)的引用決定。
1、強(qiáng)引用
是指創(chuàng)建一個(gè)對(duì)象并把這個(gè)對(duì)象賦值給一個(gè)引用變量
強(qiáng)引用有引用變量指向時(shí),永遠(yuǎn)不會(huì)被垃圾回收,JVM寧愿拋出OutOfMeory錯(cuò)誤也不回收這種變量
如果想中斷強(qiáng)引用和某個(gè)對(duì)象的關(guān)聯(lián),可以顯示的應(yīng)引用變量賦值為null,這樣JVM在合適的時(shí)機(jī)就會(huì)回收該對(duì)象
2、軟引用(SoftReference)
如果一個(gè)對(duì)象只具有軟引用,內(nèi)存足夠,垃圾回收器就不會(huì)回收它
如果內(nèi)存空間不足,就會(huì)回收這些對(duì)象的內(nèi)存,只要垃圾回收器沒有回收它,該對(duì)象就可以被程序使用
軟引用可用來實(shí)現(xiàn)內(nèi)存敏感的高速緩存,比如網(wǎng)頁緩存,圖片緩存,使用軟引用可以防止內(nèi)存泄露,增強(qiáng)程序健壯性
SoftReference的特點(diǎn)是它的實(shí)例保存對(duì)一個(gè)java對(duì)象的軟引用,該軟引用的存在不妨礙垃圾回收線程對(duì)該java對(duì)象的回收
即:一旦SoftReference保存了對(duì) 一個(gè)java對(duì)象的軟引用之后,在垃圾對(duì)該java對(duì)象回收之前,SoftReference類所提供的get()方法返回java對(duì)象的強(qiáng)引用。
一旦垃圾回收該java對(duì)象之后,get()方法將返回null。
MyObject obj = new MyObject();
SoftReference softRef = ne SoftReference(obj);
此時(shí),對(duì)于這個(gè)obj對(duì)象來說,有兩個(gè)引用路徑,一個(gè)是SoftReference對(duì)象的軟引用,還有一個(gè)是變量obj的強(qiáng)引用。
所以obj對(duì)象是強(qiáng)可及對(duì)象。
隨即,我們可以結(jié)束obj對(duì)MyObject實(shí)例的強(qiáng)引用
obj = null
此后這個(gè)MyObject對(duì)象成為了軟可及對(duì)象,如果垃圾回收線程進(jìn)行垃圾回收,會(huì)回收掉軟可及對(duì)象
可與引用隊(duì)列一起使用,在垃圾回收之后,會(huì)將該weakRef引用對(duì)象放置到引用隊(duì)列中
3、弱引用
弱引用用來描述非必需的對(duì)象,當(dāng)JVM進(jìn)行垃圾回收時(shí),無論內(nèi)存充足與否,都會(huì)回收被弱引用關(guān)聯(lián)的對(duì)象
public static void main(String[] args){
WeakReference<Person> weakRef = new WeakReference<Person>(new Person("我是弱引用")); // 此時(shí)Person對(duì)象是弱可及對(duì)象
System.out.println(((Person)weakRef.get()).getName());
System.gc();
System.out.println(weakRef.get());
}
// 打印結(jié)果
我是弱引用
null
第二個(gè)輸出為null,這說明只要JVM進(jìn)行垃圾回收,被弱引用關(guān)聯(lián)的對(duì)象肯定會(huì)被回收掉。這里說的弱引用關(guān)聯(lián),是只有弱引用與之關(guān)聯(lián),如果存在強(qiáng)引用關(guān)聯(lián),就不會(huì)回收該對(duì)象,軟引用也是如此
下面,就是有強(qiáng)引用關(guān)聯(lián)的方式
public static void main(String[] args){
Person weakP = new Person("我是弱引用");
WeakReference<Person> weakRef = new WeakReference<Person>(weakP); // 此時(shí)Person對(duì)象是強(qiáng)可及對(duì)象
System.out.println(((Person)weakRef.get()).getName());
System.gc();
System.out.println(weakRef.get());
}
// 打印結(jié)果
我是弱引用
bean.Person@610455d6
可與引用隊(duì)列一起使用,在垃圾回收之后,會(huì)將該weakRef引用對(duì)象放置到引用隊(duì)列中
4、虛引用
虛引用和前面的軟引用和弱引用不一樣,它不影響對(duì)象的生命周期,如果一個(gè)對(duì)象與虛引用關(guān)聯(lián),則跟沒有引用與之關(guān)聯(lián)一樣,在任何時(shí)候都可能會(huì)被垃圾回收器回收。
需要注意的是,虛引用必須與引用隊(duì)列關(guān)聯(lián)使用