在編輯Java程序中掛掉是為什么呢?下面西安達內Java培訓(www.xatarena.cn)講師為了講清這個問題,寫了一個簡單的例子。在本例中,先初始化了一個map,然后用一個無限循環(huán)將一些鍵值對插入到map里面:
class Wrapper {
public static void main(String args[]) throws Exception {
Map map = System.getProperties();
Random r = new Random();
while (true) {
map.put(r.nextInt(), "value");
}
}
}
你可能也猜到了,這段代碼編譯執(zhí)行后無法正常結束。當我用這組參數啟動的話:
java -Xmx100m -XX:+UseParallelGC Wrapper
我會在終端中看到java.lang.OutOfMemoryError: GC overhead limit exceeded的異常信息。不過如果我調整一下堆大小或者是GC的類型的話,在我的Mac OS X 10.9.2 系統(tǒng)上用Oracle Hotspot JDK 1.7.0_45來運行,就會出現不同的情況。
比如說,我用一個較小的堆來運行這個程序,就像下面這樣:
java -Xmx10m -XX:+UseParallelGC Wrapper
應用程序會拋出一段大家更熟悉的錯誤信息然后掛掉:java.lang.OutOfMemoryError: Java heap space.
如果你換成ParallelGC以外的GC策略的話,比如說-XX:+UseConcMarkSweepGC or -XX:+UseG1GC,你將會看到由默認的異常處理器所拋出的異常,并且你看不到堆棧信息了,因為堆已經沒有空間了,甚至連異常的堆棧信息都沒法填充了,因此它在創(chuàng)建異常的時候就掛掉了:
My Precious:examples vladimir$ java -Xmx100m -XX:+UseConcMarkSweepGC Wrapper
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
這說明了什么?當資源緊缺的時候,你根本沒法判斷你的應用程序是怎么掛掉的,因此不要指望能出現你所預期的一系列錯誤提示。從上面這個例子中可以看到,你的程序可能會以三種完全不同的方式掛掉:
GC的安全性檢查失敗:一旦GC花費的時間占到98%以上的話,JVM就會宣告投降了: java.lang.OutOfMemoryError: GC overhead limit exceeded.
無法為下一個操作分配足夠的內存:如果無法滿足下一條指令所需要分配的內存的話,你會收到一條"java.lang.OutOfMemoryError: Java heap space" 的錯誤信息。 |
 |
|