2012-11-07 87 views
16

想了很長時間的通用方式來提出這個問題(並沒有找到一個),我只是要問它作爲一個具體的例子:當運行時JVM內存不足以分配時會發生什麼?

假設我有一臺Linux機器有1 Gb它可以分配給進程的內存(物理和交換總計1 Gb)。

我在機器上安裝了標準的Oracle Hotspot JVM版本7。如果在給定時刻,也有運行這樣只有400 Mb內存1 GB的是免費的足夠的程序,我在用下面的JVM標誌的那一刻開始Java程序:

java -Xms256m -Xmx512m -jar myJar.jar 

什麼happends? :

答:JVM無法立即啓動,因爲它會嘗試分配所有512 Mb內存並失敗(由於目前沒有足夠的可用內存)?

如果JVM啓動:

如果在某些點上運行的Java進程將需要超過400 MB的內存(現在仍然有隻有400 MB的內存,這比什麼當前Java進程已經使用不含其它),會發生什麼情況:

B. Java過程會失敗,併發生OutOfMemroyError?

C.它會失敗與其他(標準)錯誤? D.它是未定義的行爲?

D.是不確定的行爲?

+1

我相信選項(B),但是如果只有200 Mb(少於Xms)可用,然後選項A. – Scorpion

回答

9

-Xmx只是限定了堆的最大尺寸。它不能保證有太多的記憶與否。它只能確保堆永遠不會超過給定的值。也就是說,選項B)會發生,將引發outOfMemoryError。

+0

謝謝。但是,那麼我可以假設,如果我爲Xms *傳遞一個大於當前空閒內存大小的值(即在我的示例中,如果我將Xms更改爲500m,那麼JVM將無法啓動? –

+1

看看這裏:http://stackoverflow.com/questions/3648454/what-happens-if-you-specify-max-heap-size-greater-than-available-ram – Polygnome

+0

感謝您的鏈接,該問題清除解決了我的一些問題,但它只涉及Xmx在系統上的實際總內存。我想知道當Xmx值會釋放當前可用(可用)內存(物理和交換)可用(但不會超過系統的總體物理安裝內存,也不會違反32位內存限制)時會發生什麼情況 –

2

OutOfMemroyError將是「當Java虛擬機由於內存不足而無法分配對象時拋出,並且無法使垃圾收集器獲得更多內存。」

所以,本質上,「B. Java進程失敗,OutOfMemroyError

+0

感謝您的答案。我是否可以假設對於所有熱點實現(即在所有可以使用熱點JVM的操作系統上)都是如此? –

6

假設我有一臺Linux機器,它具有1 Gb的內存,可以分配給進程(物理和交換總計1 Gb)。

我的第一反應是,除非你在談論電話,我會得到更多的記憶。您可以購買少於100美元的16 GB(b =位,B =字節)。

JVM無法立即啓動,因爲它會嘗試分配所有512 Mb內存並失敗(由於目前沒有足夠的可用內存)?

如果系統沒有512 MB(加上一些開銷),因爲它在啓動時分配用於堆的連續虛擬內存,可能會發生這種情況。

即使您有550 MB空閒空間,程序也可能無法啓動,因爲它需要加載的不僅僅是堆。

Java進程將失敗並出現OutOfMemoryError?

如果您的程序在運行時使用512 MB,則無論您的計算機具有多少內存,這都會發生。此錯誤只會在JVM啓動後發生。如果無法啓動,您將不會收到此錯誤。

它會失敗並出現一些其他(標準)錯誤嗎?

如果在程序啓動後用完了交換空間,這是可能的。這種情況非常罕見,只發生在一臺嚴重超載的機器上。我所看到的是JVM由於低級別的操作系統故障而分配內存而崩潰。

Java 6 Update 25 VM crash: insufficient memory

+0

+1特別是關於未定義行爲的最後一句話。 –

+1

@Peter - 我不完全確定,但我相信如果系統的內存少於使用'-xmx'指定的內存,JVM將被設置爲可用的最大值,並且不會立即崩潰。 ---但我不知道是否同樣適用於'-xms'。可能不會。---我也認爲答案應該更廣泛一些,而不是圍繞'512 MB'的例子,以便將來可能會發現這個問題的其他社區成員更清楚。 --- +1爲優秀的答案。特別是最後一節。 – XenoRo

+1

-xms設置對於它是否會啓動沒有任何影響。它告訴GC容易增長到這個尺寸。注意:「Hello World」程序不會因爲您將其設置爲最小值而使用最小大小。 –

1

JVM進程將在虛擬內存中運行,因此運行其他進程的分配問題是相關的,但不是完全確定性的。

當JVM無法分配更多的內存(無論何種原因),這個過程本身不會終止,而是開始投擲OutOfMemoryError在JVM中,而不是外部的JVM。換句話說,JVM會繼續運行,但在JVM中運行的程序通常會失敗,因爲大多數程序不能充分處理低內存條件。在這種相當常見的情況下,當程序沒有做任何事情來處理錯誤時,JVM將終止程序並退出。最終,這是來自內存分配,但不是直接如此。一段代碼可以在內存不足的情況下自行縮放並繼續運行。

其他人指出,有時候JVM本身並不能很好地處理低內存,但這是一個非常極端的情況。

2

如果你有太多的佔用內存,以至於空閒空間甚至無法維持一個空閒的JVM,你會得到一些錯誤,說明程序沒有足夠的內存,或者JVM會崩潰。

如果您可以運行JVM,則可以使用-Xmx指定堆空間的限制。這並不意味着所有的堆將在啓動時由JVM分配 - 這只是一個內部限制。如果JVM希望增加堆空間,但內存不足,或者需要比-Xmx指定的更多的堆,那麼在當前運行的Java程序中會出現OutOfMemoryError。

在非常極端的情況下,當JVM運行時,可能會耗盡可用內存,同時JVM需要更多內存用於內部操作(而不是堆空間) - 然後JVM會告訴您需要更多的記憶,但是不能得到任何東西,並終止,否則將會徹底崩潰。

+0

我有過程中xms和xmx是相同的,雖然我的過程有時在我的測試env崩潰,因爲內存不多,我假設低內存殺死我的進度,但我無法找到一個OOM錯誤或OOM堆轉儲文件(我轉在選項上)。如果我爲什麼沒有OOM文件,我會假設是否正確? – Jaskey

相關問題