一個java程序發生了OOM後,該程序或服務一定會被殺死嗎?科技小館2020-07-11 10:26:07

不一定。

一個執行緒 OOM 後,其他執行緒是可以正常執行的,但是記憶體洩露之後可能會導致整個程式記憶體溢位,最終程式不可用。

那麼我們下面說一下,一個執行緒 OOM 了,為什麼其他執行緒不受影響呢?

要回答這個問題,我們先來回想一下 java 的記憶體結構。如下圖所示:

一個java程序發生了OOM後,該程序或服務一定會被殺死嗎?

我們知道,多執行緒的時候,每個執行緒都擁有一個棧和一個程式計數器。棧和程式計數器用來儲存執行緒的執行歷史和執行緒的執行狀態,是執行緒私有的資源。堆是執行緒共享的,所以理論上一個執行緒 OOM 了,其他執行緒應該受影響才對啊,實際上卻並不是,這是什麼原因呢?

有興趣的可以按照我下面的這段程式碼自己去跑一下,測試一下這個記憶體溢位。

一個java程序發生了OOM後,該程序或服務一定會被殺死嗎?

然後結合 JvisualVM 工具,你會看到,在程式記憶體溢位之後,溢位的記憶體的執行緒所佔的記憶體會被快速釋放。如下圖所示

一個java程序發生了OOM後,該程序或服務一定會被殺死嗎?

根據上圖,我們可以得出當一個執行緒丟擲 OOM 異常後,它所佔據的記憶體資源會被快速的釋放掉,從而不會影響其他執行緒的執行!

另外當一個執行緒 OutOfMemoryError 後,如果這個 OutOfMemoryError 被捕獲,那麼 catch 之後吞掉的話程式還能試著繼續執行。發生 OutOfMemoryError 之後,只是當前這個執行緒申請更多的記憶體的時候不被 JVM 允許,所以會丟擲 OutOfMemoryError 異常。當丟擲 OutOfMemoryError 異常後,當前這個執行緒會被退出,它所佔的記憶體會被 JVM 清理掉。

那麼 JVM 為什麼要這麼設計呢?

答案是,Java 程式通常不是為了適應意外的異常而設計的,OOM 之後可能導致應用狀態不一致,建議最好重啟。

一個java程序發生了OOM後,該程序或服務一定會被殺死嗎?千尋知識小站2020-07-11 08:45:09

不一定。有的oom,java程序會退出,有時不會,程序還在,但是請求無法響應。