學了這么久的Java,才知道Java的對象引用類型有4種。所以,趕緊把不知道的東西補上!
對于需要長期運行的應用程序來說,如果無用的對象所占用的內存空間不能得到即時的釋放的話,那么在一個局部的時間段內便形成了事實上的內存泄露。
以前我們學過,如果要及時地釋放內存,最穩妥的方法就是使用完對象之后,立刻執行"object=null"語句。當然,這也是一種理想狀態。
JDK里面引入了4種對象引用類型,可以算是強行的調用System.gc()這個的垃圾回收的方法了。
強引用:前面我們用的全部對象都是強引用類型的。這個就顯示地執行"object=null"語句。
軟引用:被軟引用的對象,如果內存空間足夠,垃圾回收器是不會回收它的,如果內存空間不足,垃圾回收器將回收這些對象占用的內存空間。軟件引用對應著java.lang.ref.SoftReference類,一個對象如果要被軟引用,只需將其作為參數傳入SoftReference類的構造方法中就行了。感覺還是比較簡單而且容易理解。
弱引用:與前面的軟引用相比,被弱引用了的對象擁有更短的內存時間(也就是生命周期)。垃圾回收器一旦發現了被弱引用的對象,不管當前內存空間是不是足夠,都會回收它的內存,弱引用對應著java.lang.ref.WeakReference類,同樣的道理。一個對象如果想被弱引用,只需將其作為參數傳入WeakReference類的構造方法中就行了。
虛引用:虛引用不是一種真實可用的引用類型,完全可以視為一種“形同虛設”的引用類型。設計虛引用的目的在于結合引用關聯隊列,實現對對象引用關系的跟蹤(太高科技了,這幾句話。目前還不知道是什么意思)。虛引用對應著java.lang.ref.PhantomReference類。一個對象如果要被虛引用,只需將其作為參數傳入PhantomReference類的構造方法中就行了,同時作為參數傳入的還有引用關聯隊列java.lang.ref.ReferenceQueue的對象實例。(沒懂)
SoftReference,WeakReference,PhantomReference類都繼承自java.lang.ref.Reference抽象類。Reference抽象類定義了clear() 方法用于撤銷引用關系,get()方法用于返回被引用的對象。
摘抄一段代碼示例:
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.Set;
import java.util.HashSet;
public class TestReferences
{
public static void main(String[] args)
{
int length=10;
//創建length個MyObject對象的強引用
Set<MyObject> a = new HashSet<MyObject>();
for(int i = 0; i < length; i++)
{
MyObject ref=new MyObject("Hard_" + i);
System.out.println("創建強引用:" +ref);
a.add(ref);
}
//a=null;
System.gc();
//創建length個MyObject對象的軟引用
Set<SoftReference<MyObject>> sa = new HashSet<SoftReference<MyObject>>();
for(int i = 0; i < length; i++)
{
SoftReference<MyObject> ref=new SoftReference<MyObject>(new MyObject("Soft_" + i));
System.out.println("創建軟引用:" +ref.get());
sa.add(ref);
}
System.gc();
//創建length個MyObject對象的弱引用
Set<WeakReference<MyObject>> wa = new HashSet<WeakReference<MyObject>>();
for(int i = 0; i < length; i++)
{
WeakReference<MyObject> ref=new WeakReference<MyObject>(new MyObject("Weak_" + i));
System.out.println("創建弱引用:" +ref.get());
wa.add(ref);
}
System.gc();
//創建length個MyObject對象的虛引用
ReferenceQueue<MyObject> rq = new ReferenceQueue<MyObject>();
Set<PhantomReference<MyObject>> pa = new HashSet<PhantomReference<MyObject>>();
for(int i = 0; i < length; i++)
{
PhantomReference<MyObject> ref = new PhantomReference<MyObject>(new MyObject("Phantom_" + i), rq);
System.out.println("創建虛引用:" +ref.get());
pa.add(ref);
}
System.gc();
}
}
class MyObject
{
private String id;
public MyObject(String id)
{
this.id = id;
}
public String toString()
{
return id;
}
public void finalize()
{
System.out.println("回收對象:" + id);
}
}