web-dev-qa-db-ja.com

JVMが実行時に割り当てるメモリが不足するとどうなりますか?

この質問を提起する一般的な方法を長い間考えた後(そしてそれを見つけることができなかった場合)、具体的な例として尋ねます。

プロセスに割り当てることができる1 Gbのメモリを備えたLinuxマシンがあるとします(物理およびスワップの合計は1 Gb)。

マシンに標準のOracle Hotspot JVMバージョン7をインストールしています。ある時点で、1 Gbのうち400 Mbだけが空いているような十分なプログラムが実行されている場合、Javaプログラムをその時点で次のJVMフラグで開始します。

Java -Xms256m -Xmx512m -jar myJar.jar

どうしたの? :

A. JVMは512 Mbのメモリをすべて割り当てようとして失敗するので、すぐに起動できませんか(現時点で利用可能なメモリが十分にないため)。

jVMが起動した場合:

ある時点で、実行中のJavaプロセスは400Mbを超えるメモリを必要とする場合(そして、現在のメモリ以外に解放されているメモリは400Mbしかない)Java =プロセスはすでに使用されています)、どうなりますか:

B. JavaプロセスはOutOfMemroyErrorで失敗しますか?

C.他の(標準の)エラーで失敗しますか?

D.未定義の動作ですか?

20
Shivan Dragon

-Xmxは、ヒープの最大サイズを定義するだけです。メモリが多いかどうかは保証されません。ヒープが指定された値より大きくなることはありません。つまり、オプションBが発生します。outOfMemoryErrorがスローされます。

9
Polygnome

プロセスに割り当てることができる1 Gbのメモリを備えたLinuxマシンがあるとします(物理およびスワップの合計は1 Gb)。

私の最初の返答は、あなたが電話について話しているのでなければ、私はより多くのメモリを手に入れるでしょう。 $ 100未満で16 GB(b =ビット、B =バイト)を購入できます。

jVMは512 Mbのメモリをすべて割り当てようとして、すぐに起動できません(現時点で利用可能なメモリが十分にないため)。

これは、システムが起動時にヒープに使用される連続的な仮想メモリを割り当てるため、システムに512 MB(およびいくつかのオーバーヘッド)がない場合に発生する可能性があります。

550 MBの空き容量がある場合でも、ヒープだけではなくロードする必要があるため、プログラムが起動しない可能性があります。

JavaプロセスはOutOfMemoryErrorで失敗しますか?

これは、マシンのメモリ量に関係なく、プログラムの実行中に512 MBを使用すると発生する可能性があります。このエラーは、JVMが起動した後にのみ発生します。開始できない場合、このエラーは発生しません。

他の(標準の)エラーで失敗しますか?

これは、プログラムの開始後にスワップ領域が不足した場合に可能です。これはまれであり、非常に過負荷のマシンでのみ発生します。私が見たのは、メモリを割り当てるための低レベルのOSエラーが原因でJVMがクラッシュすることです。

Java 6 Update 25 VMクラッシュ:メモリ不足

7
Peter Lawrey

占有メモリが多すぎて空き容量がアイドル状態のJVMを維持できない場合、プログラムに十分なメモリがないことを示すエラーが発生するか、JVMがクラッシュします。

JVMを実行できる場合は、-Xmxを使用してヒープ領域の制限を指定できます。これは、すべてのヒープが開始時にJVMによって割り当てられることを意味するのではなく、内部制限にすぎません。 JVMがヒープスペースを増やしたいが、十分なメモリがない場合、または-Xmxで指定されたよりも多くのヒープが必要な場合、現在実行中のJavaプログラムでOutOfMemoryErrorが発生します。

非常に極端な状況では、JVMの実行中に空きメモリが不足する可能性があります。同時に、JVMは内部操作(ヒープスペースではなく)のためにより多くのメモリを必要とします。しかし、何も取得できず、終了するか、完全にクラッシュします。

2
Jakub Zaverka

OutOfMemroyErrorになります "Javaメモリが不足しているため仮想マシンがオブジェクトを割り当てることができない場合にスローされます、そしてガベージコレクターはこれ以上メモリを利用できません。」

つまり、本質的に、 "B。JavaプロセスはOutOfMemroyError"で失敗します

2
XenoRo

JVMプロセスは仮想メモリで実行されるため、実行中の他のプロセスの割り当ての問題は関連しますが、完全に決定的ではありません。

JVMが(何らかの理由で)より多くのメモリを割り当てることができない場合、プロセス自体は終了せず、OutOfMemoryErrorwithin JVMをスローし始めますが、JVMの外部にはありません。つまり、JVMは引き続き実行されますが、JVM内で実行されているプログラムは、ほとんどが低メモリ状態を適切に処理しないため、通常は失敗します。このかなり一般的なケースでは、プログラムがエラーを処理するために何もしない場合、JVMはプログラムを終了して終了します。最終的に、これはメモリ割り当てによるものですが、直接そうではありません。コードの一部がメモリ不足の状態で縮小され、実行を継続する可能性があります。

他の人が指摘したように、JVM自体がメモリ不足をうまく処理できない場合がありますが、これはかなり極端な状態です。

1
eh9