32ビットWindowsで実行されているJava SEに1400メガバイトを常に割り当てることができましたXP(Java 1.4、1.5、および1.6)。
Java -Xmx1400m ...
今日、XP 1.5_16および1.6.0_07を使用して新しいWindows Javaマシンで同じオプションを試し、エラーが発生しました。
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
試行錯誤の結果、このマシンに割り当てることができるのは1200メガバイトであるようです。
あるマシンが1400を許可し、別のマシンが1200を許可する理由は何ですか?
編集:マシンには4GBのRAMがあり、約3.5GBのWindowsが認識できます。
Windowsには仮想メモリ管理があり、JVMに必要なのは連続したメモリのみであることに注意してくださいアドレス空間内。したがって、システムで実行されている他のプログラムが必ずしもヒープサイズに影響を与えることはありません。邪魔になるのは、アドレススペースに読み込まれるDLLです。残念ながら、リンク中のDLLの再配置を最小限に抑えるWindowsの最適化により、アドレス空間が断片化される可能性が高くなります。通常のものとは別にアドレス空間に侵入する可能性が高いものには、セキュリティソフトウェア、CBTソフトウェア、スパイウェア、その他のマルウェアが含まれます。差異の原因として考えられるのは、さまざまなセキュリティパッチ、Cランタイムバージョンなどです。デバイスドライバーやその他のカーネルビットには、独自のアドレススペース(4 GBの32ビットスペースの他の2 GB)があります。
could JVMプロセスでDLLバインディングを試して、DLLをよりコンパクトなアドレススペースにリベースしようとしています。面白くないが、もしあなたが必死なら...
または、64ビットWindowsと64ビットJVMに切り替えることができます。他の人が示唆していることにもかかわらず、それはより多くのRAMを噛みますが、muchより連続した仮想アドレス空間を持ち、2GBを連続して割り当てるのは簡単です。
これは、連続したメモリに関係しています。
これは私がオンラインで見つけたいくつかの情報です おそらく「VM god」から以前にそれを尋ねる誰かのために:
ヒープに連続したメモリ領域が必要な理由は、ヒープの先頭からの(スケーリングされた)オフセットによってインデックス付けされた多数のサイドデータ構造があるためです。たとえば、ヒープの512バイトごとに1バイトを持つ「カードマーク配列」でオブジェクト参照の更新を追跡します。ヒープに参照を格納する場合、カードマーク配列の対応するバイトをマークする必要があります。ストアの宛先アドレスを右にシフトし、それを使用してカードマーク配列のインデックスを作成します。 Javaではできない、C++でプレイする(する必要がある)算術ゲームの楽しいアドレッシング。
通常、適度な連続領域を取得するのに問題はありません(Windohでは最大約1.5GB、Solarisでは最大約3.8GB。YMMV)。 Windohsでは、問題は主に、JVMが起動する前にロードされ、アドレススペースを分割するライブラリがいくつかあることです。/3GBスイッチを使用してもこれらのライブラリのリベースは行われないため、依然として問題があります。
チャンクヒープを作成する方法は知っていますが、それらを使用するとオーバーヘッドが発生します。 32ビットJVMの大きなヒープよりも、ストレージ管理を高速化するためのリクエストが多くあります。本当に大きなヒープが必要な場合は、64ビットJVMに切り替えます。連続したメモリが必要ですが、64ビットのアドレス空間を取得する方がはるかに簡単です。
WindowsのJavaヒープサイズの制限は次のとおりです。
これは、より大きなJavaヒープを取得するのに役立ちませんが、これらの値を超えることはできないことがわかりました。
Oracle JRockit は、不連続のヒープを処理できますが、/ 3GBスイッチを使用したWindows 2003/XPでは、2.8 [GB]のJavaヒープサイズを使用できます。断片化は、Javaヒープの大きさに大きく影響するようです。
JVMには連続メモリが必要であり、他に何が実行されているか、以前に何が実行されていたか、およびWindowsがメモリを管理した方法に応じて、最大1.4GBの連続メモリを取得できます。 64ビットWindowsではより大きなヒープが許可されると思います。
この応答が示すように、Windowsがどのように構成されているかにより関係があると思います。 Java -Xmx Option
さらにいくつかのテスト:768MBの物理XP(および仮想メモリ)のみの古いWindows RAMマシンで1300MBを割り当てることができました。 2GB RAMマシンでは、1220MBしか取得できません。他のさまざまな企業マシン(古いWindows XPを使用)では、1400MBを取得できました。 1220MBの制限があるマシンはかなり新しい(Dellから購入したばかり)ので、新しい(そしてより肥大化した)WindowsとDLL(Window XP Pro Version 2002 SP2を実行している)があるかもしれません。
(メモリが限られている)virtuozzo VPSからJavaプログラムを実行すると、このエラーメッセージが表示されました。メモリ引数を指定していなかったので、デフォルトが高すぎるため、明示的にsmallの量を設定する必要がありました。例えば。 -Xmx32m(明らかに、実行するプログラムに応じて調整する必要があります)。
質問者のように大量のメモリを指定せずに他の誰かが上記のエラーメッセージを受け取った場合に備えて、これをここに置いてください。
巨大なブロックを割り当てる場合、SunのJDK/JREは連続した量のメモリを必要とします。
OSおよび初期アプリは、ロード中に使用可能なRAMを断片化するビットとピースを割り当てる傾向があります。連続したブロックが利用できない場合、Sun JDKはそれを使用できません。 BeaのJRockit(Oracleが取得)は、断片からメモリを割り当てることができます。
誰もが連続した記憶について答えているようですが、より差し迫った問題を認めることを怠っています。
100%の連続したメモリ割り当てでも、32ビットWindows OSでは2 GiBヒープサイズを使用できません(*デフォルト)。これは、32ビットのWindowsプロセスが2 GiB以上のスペースをアドレスできないためです。
Javaプロセスには、perm gen(pre Java 8)、スレッドごとのスタックサイズ、JVM /ライブラリオーバーヘッド(各ビルドでかなり増加します)ヒープに加えてすべて。
さらに、JVMフラグとそのデフォルト値はバージョン間で変更されます。以下を実行するだけで、いくつかのアイデアが得られます。
Java -XX:+PrintFlagsFinal
多くのオプションは、ヒープ内外のメモリ分割に影響します。多かれ少なかれ2 GiB_で遊ぶことができます...
this 私の回答の一部を再利用するには(Tomcatについてですが、Javaプロセスに適用されます):
Windows OSは、32ビットプロセスのメモリ割り当てを合計で2 GiBに制限します(デフォルト)。
プロセスに割り当てられた他のメモリ(JVM /ライブラリのオーバーヘッド、perm genスペースなど)もあるため、[1.5] GiBヒープスペースのみを割り当てることができます。
2ビットWindowsが2 GBのプロセスアドレススペース制限を課すのに、64ビットWindowsは4 GBの制限を課す理由
その他の最新のオペレーティングシステム[cough Linux]では、32ビットプロセスが4 GiBアドレス可能スペースのすべて(またはほとんど)を使用できます。
ただし、64ビットWindows OSは、32ビットプロセスの制限を4 GiB(32ビットでは3 GiB)に増やすように構成できます。
http://msdn.Microsoft.com/en-us/library/windows/desktop/aa366778(v = vs.85).aspx
ページングサイズを増やす方法は次のとおりです。