WeakHashMap使用弱引用來作為Map的Key,利用虛擬機的垃圾回收機制能自動釋放Map中沒有被使用的條目。但是WeakHashMap釋放條目是有條件的:首先條目的Key在系統中沒有強引用指向;另外,條目的釋放是在垃圾回收之後第一次訪問這個WeakHashMap時完成的。
而當我們想要獲取一個Integer對象時,為了利用Integer類本身的緩存,減少堆中Integer對象的重復申請和釋放,我們通常會采用Ingeter.valueOf(int)方法來獲取Integer對象,而不是直接使用new Integer(int)。 Integer類會將0~127的整數對象緩存在一個Map中,而這個Map中保存的是這些Integer對象的強引用,如果我們想要使用Integer作為WeakHashMap的Key,那就需要注意不能再使用Integer.valueOf(int)方法獲取WeakHashMap中Key的對象,否則所有以0~127作為Key的條目不會被自動釋放。
下面一段代碼比較了三種方式獲取到的Integer對象分別作為WeakHashMap的Key的區別,三種方式分別是:1.使用Integer.valueOf(int);2.使用new Integer(int);3.使用Java的自動裝箱。
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<Integer, String> wmap = new WeakHashMap<Integer, String>();
for(int i = 0; i <= 160; i += 20){
wmap.put(Integer.valueOf(i), "" + i);
}
System.out.println("Before GC1: ");
System.out.println(wmap);
System.gc();
System.out.println("After GC1: ");
System.out.println(wmap);
wmap.clear();
for(int i = 0; i <= 160; i += 20){
wmap.put(new Integer(i), "" + i);
}
System.out.println("Before GC2: ");
System.out.println(wmap);
System.gc();
System.out.println("After GC2: ");
System.out.println(wmap);
wmap.clear();
for(int i = 0; i <= 160; i += 20){
wmap.put(i, "" + i);
}
System.out.println("Before GC3: ");
System.out.println(wmap);
System.gc();
System.out.println("After GC3: ");
System.out.println(wmap);
}
運行結果如下:
Before GC1:
{120=120, 60=60, 160=160, 40=40, 140=140, 80=80, 20=20, 100=100, 0=0}
After GC1:
{120=120, 60=60, 40=40, 80=80, 20=20, 100=100, 0=0}
Before GC2:
{120=120, 60=60, 160=160, 40=40, 140=140, 80=80, 20=20, 100=100, 0=0}
After GC2:
{}
Before GC3:
{120=120, 60=60, 160=160, 40=40, 140=140, 80=80, 20=20, 100=100, 0=0}
After GC3:
{120=120, 60=60, 40=40, 80=80, 20=20, 100=100, 0=0}
可以看到第一種方式使用Integer.valueOf(int)得到的Key,垃圾回收之後只釋放了140和160兩個條目,128一下都仍然保留;使用new Integer(int)得到的Key垃圾回收之後全部被釋放。值得注意的是,我們利用自動裝箱得到的Integer對象和使用Integer.valueOf(int)結果一樣,說明自動裝箱也會利用Integer類的緩存。在使用Integer或類似的存在緩存的對象作為WeakHashMap的Key的時候,一定要注意對象緩存中對Key對象是否存在無法釋放的強引用,否則WeakHashMap自動釋放不使用條目的效果無法達到。
Java 8 中 HashMap 的性能提升 http://www.linuxidc.com/Linux/2014-04/100868.htm
Java 8 的 Nashorn 引擎 http://www.linuxidc.com/Linux/2014-03/98880.htm
Java 8簡明教程 http://www.linuxidc.com/Linux/2014-03/98754.htm
Java通過java.io.FileInputStream讀取txt文本 http://www.linuxidc.com/Linux/2014-05/102047.htm