//SizableObject could simply be a large array, e.g. byte[]
//In the JavaGaming discussion it was a BufferedImage
bigObject = new SizableObject(size);
long endTime = System.currentTimeMillis();
++numObjects;
// We print stats for every two seconds
if (endTime - startTime >= 2000) {
System.out.println("Objects created per 2 seconds = " + numObjects);
startTime = endTime;
numObjects = 0;
}
}
}
這個例子有個簡單的循環,創建一個大型對象并且將它賦給同一個變量,每隔兩秒鐘報告一次所創建的對象個數?,F在的 Java 虛擬機采用 generational 垃圾收集機制,新的對象創建之后放在一個內存空間(取名 Eden)內,然后將那些在第一次垃圾收集以后仍然保留的對象轉移到另外一個內存空間。在 Eden,即創建新對象時所在的新一代空間中,收集對象要比在“老一代”空間中快得多。但是假如 Eden 空間已經滿了,沒有空間可供分配,那么就必須把 Eden 中的對象轉移到老一代空間中,騰出空間來給新創建的對象。假如沒有顯式地賦空變量,而且所創建的對象足夠大,那么 Eden 就會填滿,并且垃圾收集器就不能收集當前所引用的這個大型對象。所產生的后果是,這個大型對象被轉移到“老一代空間”,并且要花更多的時間來收集它。
通過顯式地賦空變量,Eden 就能在新對象創建之前獲得自由空間,這樣垃圾收集就會更快。實際上,在顯式賦空的情況下,該循環在兩秒鐘內創建的對象個數是沒有顯式賦空時的5倍??但是僅當您選擇創建的對象要足夠大而可以填滿 Eden 時才是如此, 在 Windows 環境、Java虛擬機 1.4 的默認配置下大概需要 500KB。那就是一行賦空操作產生的 5 倍的性能差距。但是請注重這個性能差別產生的原因是變量的作用域不正確,這正是賦空操作發揮作用的地方,并且是因為所創建的對象非常大。