2012-08-02 21 views
0

我一直認爲OutOfMemoryError重新啓動JVM。
但我看到其中一個OutOfMemoryError發生這不是從代碼抓到一個行爲(其實我甚至不知道這是可能的)
JVM繼續(核心轉儲雖然生產)。
任何人都可以幫助我理解這種行爲嗎?Java中的OutOfMemoryError行爲

回答

2

OutOfMemoryError向一個線程報告其內存分配失敗。

int count = 0; 
long start = System.currentTimeMillis(); 
for (int i = 0; i < 10000000; i++) { 
    try { 
     long[] longs = new long[Integer.MAX_VALUE]; 
    } catch (OutOfMemoryError e) { 
     count++; 
    } 
} 
long time = System.currentTimeMillis() - start; 
System.out.printf("Got %,d OutOfMemoryErrors in %.1f seconds%n", count, time/1e3); 

打印

Got 10,000,000 OutOfMemoryErrors in 3.9 seconds 
3

OutOfMemoryError是一個例外,就像任何其他。它當然不會重新啓動JVM。它可能會導致它發生的線程結束,但只有在任何地方都沒有捕獲到時纔會發生。您可能看到的不是核心轉儲,而僅僅是捕獲的異常的堆棧跟蹤以及使用e.printStackTrace()明確打印的堆棧跟蹤。

+0

所以,當我看到occusionally一個JVM重啓,這是什麼意思? – Jim 2012-08-02 09:23:25

+1

這意味着一個JVM啓動器實際上明確地負責重新啓動。它與Java本身無關。 – 2012-08-02 09:27:02

+0

所以你說,儘管轉儲表示堆已經被使用,但JVM仍然不會自行終止,在這種情況之後它能做什麼? – Jim 2012-08-02 09:30:21

1

OutOfMemory只是當由於缺少可用內存而無法實例化對象時引發的錯誤。這不會停止JVM,就像沒有其他異常或錯誤一樣。

1

否可丟棄重新啓動JVM。 OutOfMemoryError與其他運行時異常或錯誤一樣:它傳播調用堆棧直到被捕獲。如果不是,則線程的UncaughtExceptionHandler處理此異常,通常是終止線程並打印異常的堆棧跟蹤。

+0

所以當我偶爾看到一個JVM重啓時,這是什麼意思? – Jim 2012-08-02 09:23:34

+0

可能您已經有一些腳本或工具檢測到JVM不再運行,並且重新啓動它。 JVM不會自行重啓。它可能完全崩潰,但不能重新啓動。 – 2012-08-02 09:27:56

+0

所以,你說即使轉儲表示堆被使用,JVM仍然不會自行終止,在這種情況之後它能做什麼? – Jim 2012-08-02 09:31:07

1

OutOfMemoryError或任何異常都不會重新啓動JVM。

I am seeing a behavior where an OutOfMemoryError occurs this is not caught from the code

---->OutOfMemoryError繼承java.lang.Error。錯誤描述了可能很少或難以從計算機內存耗盡中恢復的環境問題。您不需要處理Error類對象,但您應該使用Throwable來處理它們。這些應該被視爲 環境缺陷。

看一看Exception Hierarchy

+0

設計良好的應用程序非常需要處理任何Throwables,包括OOME's。你想看到你的服務器崩潰只是因爲一個請求OOME'D或SOE'd?我也不會。 – 2012-08-02 10:23:46

+0

我也不會更新答案。 :) – 2012-08-02 10:32:07