Windows XPでのJava最大メモリ


103

32ビットWindows XP(Java 1.4、1.5および1.6)で実行されるJava SEには、常に1400メガバイトを割り当てることができました。

java -Xmx1400m ...

今日、Java 1.5_16と1.6.0_07を使用して新しいWindows XPマシンで同じオプションを試したところ、エラーが発生しました。

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

試行錯誤の結果、1200メガバイトがこのマシンに割り当てることができる最大容量のようです。

1つのマシンで1400が許可され、別のマシンでは1200しか許可されない理由はありますか?

編集:マシンには、Windowsが認識できる約3.5GBの4GBのRAMが搭載されています。


64ビットWindowsXPシステムはまれですが、少なくとも私の経験では、32ビットシェルで実行するか64ビットシェルで実行するかの最大値の違いに気付くでしょう。
djangofan 2013年

回答:


124

Windowsには仮想メモリ管理があり、JVM にはアドレス空間で連続ているメモリのみが必要であることを覚えておいてください。したがって、システムで実行されている他のプログラムがヒープサイズに必ずしも影響を与えるとは限りません。あなたの邪魔になるものはあなたのアドレス空間にロードされるDLLです。残念ながら、リンク中のDLLの再配置を最小限に抑えるWindowsの最適化により、フラグメント化されたアドレス空間が存在する可能性が高くなります。通常のものとは別に、アドレス空間に侵入する可能性のあるものには、セキュリティソフトウェア、CBTソフトウェア、スパイウェア、およびその他の形式のマルウェアが含まれます。差異の原因として考えられるのは、異なるセキュリティパッチ、Cランタイムバージョンなどです。デバイスドライバーと他のカーネルビットには、独自のアドレススペースがあります(4GB 32ビットスペースの他の2GB)。

あなたは可能性JVMプロセスでDLLバインディングを調べて、DLLをよりコンパクトなアドレス空間にリベースしようとすることを検討ます。面白くないけど、必死なら...

または、64ビットWindowsと64ビットJVMに切り替えることもできます。他の人が示唆したにもかかわらず、RAMをより多く消費しますが、より連続した仮想アドレス空間があり、2GBを連続して割り当てることは簡単です。


5
プロセスエクスプローラーを使用して、メモリdllが読み込まれている場所を確認します。多くの場合、一部の更新されたドライバーは、アドレス空間の真ん中に留まります。REBASEコマンドを使用すると、簡単にこれらをプッシュできます。ただし、dllは再度更新され、問題が発生する可能性があることに注意してください。
brianegge 2009

2
私はこれを回答として受け入れたことはありませんが、stackoverflowはそれを回答済みとしてマークしました。
スティーブクオ

@ Christopher、32ビットWindows XPで64ビットJVMを使用することは可能ですか?
Pacerier 2014年

@Pacerier申し訳ありませんが、あなたのクエリを逃しました。私の知る限り、それは不可能です。OS Xには、32ビットカーネルで64ビットのユーザースペースにいくつかのトリックがありましたが、Windowsではそのようなことは聞いたことがありません。
Christopher Smith、

@ ChristopherSmith、Btw、あなたは「システムで実行されている他のプログラムは必ずしもヒープサイズに影響を与えるべきではない」と述べました。もしそうなら、この結果をどのように説明しますか:stackoverflow.com/questions/9303889/…
Pacerier

50

これは連続したメモリに関係しています。

これは、おそらく「VMの神」からのものだと以前に誰かに尋ねたときにオンライン見つけた情報です

ヒープに連続したメモリ領域が必要な理由は、ヒープの先頭からの(スケーリングされた)オフセットによってインデックスが付けられた一連のサイドデータ構造があるためです。たとえば、オブジェクト参照の更新を、512バイトのヒープごとに1バイトの「カードマーク配列」で追跡します。ヒープに参照を格納するとき、カードマーク配列の対応するバイトをマークする必要があります。ストアの宛先アドレスを右シフトし、それを使用してカードマーク配列にインデックスを付けます。C ++でプレイする必要がある(:-) Javaで実行できない楽しいアドレッシング算術ゲーム。

通常、適度な連続した領域(Windowsでは最大約1.5 GB、Solarisでは最大約3.8GB。YMMV)を取得するのに問題はありません。Windohsでは、問題は主に、JVMが起動する前にロードされ、アドレス空間を分割するいくつかのライブラリがあることです。/ 3GBスイッチを使用しても、これらのライブラリはリベースされないため、これらのライブラリは依然として問題です。

チャンクヒープの作成方法はわかっていますが、使用するとオーバーヘッドが発生します。32ビットJVMの大きなヒープよりも、より高速なストレージ管理の要求があります。大きなヒープが本当に必要な場合は、64ビットJVMに切り替えてください。それでも連続したメモリが必要ですが、64ビットアドレス空間にアクセスする方がはるかに簡単です。


それはとても興味深いです。私はいつも自分になぜ1500 MBなのかと自問しましたが、今、それを手に入れました、ありがとう!
TimBüthe、2012年

3
古くからある質問についてフォローアップして申し訳ありませんが、これは私がこれまでに見た中で最良の答えです。しかし、JVMが最大ヒープサイズを取得できない場合、起動時に失敗するのはなぜですか?それは静かに最小値以上の最適なサイズに落ち着くべきではありませんか?
Stroboskop 2014

19

WindowsのJavaヒープサイズの制限は次のとおりです。

  • 32ビットJavaで可能な最大ヒープサイズ:1.8 GB
  • 32ビットJavaの推奨ヒープサイズ制限:1.5 GB(または/ 3GBオプションで1.8 GB

これは、より大きなJavaヒープを取得するのに役立ちませんが、これらの値を超えることができないことがわかりました。


10

不連続ヒープを処理できるOracle JRockitは、/ 3GBスイッチを使用するWindows 2003 / XPでJavaヒープサイズを2.85 GBにすることができます。断片化は、Javaヒープの大きさにかなりの影響を与える可能性があるようです。


6

JVMは連続メモリを必要とし、他に何が実行されているか、以前何が実行されていたか、およびウィンドウがメモリをどのように管理しているかに応じて、最大1.4GBの連続メモリを取得できる場合があります。64ビットWindowsではより大きなヒープが許可されると思います。


2
私は現代のオペレーティングシステムが連続メモリをエミュレートすると思います。80486以降、x86アーキテクチャはページングをサポートし、物理メモリの再配置を容易にしています。
Mnementh 2009

3
Mnemeth:まず、データベースやVMなどの高度なツール用のWINAPIには、Windowsでメモリを自分で管理するほうがよい特定のAPI(AllocateUserPhysicalPages)があります。第二には、ページングは80386保護モード機能ではなく、80486です
タマスCzinege

6

SunのJVMには連続したメモリが必要です。したがって、使用可能なメモリの最大量は、メモリの断片化によって決まります。特に、ドライバーのDLLは、事前定義されたベースアドレスにロードするときに、メモリを断片化する傾向があります。したがって、ハードウェアとそのドライバによって、取得できるメモリの量が決まります。

このための2つの情報源とSunエンジニアの発言:フォーラム ブログ

多分別のJVM?ハーモニーを試しましたか?彼らは非連続的なメモリを許可することを計画していたと思います。


しかし、1 GBのRAM(および仮想メモリ)だけのマシンに1300 MBを割り当てることができました。私の2GB RAMマシン(仮想メモリも搭載)は1200MBしか割り当てることができません。
スティーブKuo

ハーモニーは死んでいますね?
Pacerier

はい、「Apache Harmonyは、2011年11月16日以降、Apache Software Foundationで廃止されました。」
bobbel 2014

3

この応答が示唆するようにWindowsがどのように構成されているかは、さらに関係があると思います: Java -Xmxオプション

さらにいくつかのテスト:768 MBの物理RAM(および仮想メモリ)しかない古いWindows XPマシンに1300 MBを割り当てることができました。私の2GB RAMマシンでは、1220MBしか取得できません。他のさまざまな企業用マシン(古いWindows XP)では、1400MBを獲得できました。1220MBの制限があるマシンはかなり新しい(Dellから購入したばかり)ので、多分それは新しい(そしてより肥大化した)WindowsとDLL(それはWindow XP Proバージョン2002 SP2を実行しています)を持っています。


仮想メモリの設定によっても影響を受ける可能性があります。
スカフマン、2008年

私がテストしたすべてのマシンには、物理​​RAMの少なくとも2倍の仮想メモリがあります。
スティーブクオ

GCのパフォーマンスが非常に悪くなるので、Javaで実際に仮想メモリを実際に使用することは絶対に望まないことに注意してください。
kohlerm 2008年

2

(制限されたメモリ)virtuozzo VPSからJavaプログラムを実行すると、このエラーメッセージが表示されました。メモリ引数を指定していなかったため、明示的に小さな値を設定する必要がありました。デフォルトとして量は高すぎるされている必要があります。たとえば-Xmx32m(実行するプログラムに応じて明らかに調整する必要があります)。

他の誰かが質問者のように大量のメモリを指定せずに上記のエラーメッセージを受け取った場合に備えて、これをここに入力します。


1

巨大なブロックを割り当てる場合、SunのJDK / JREは連続した量のメモリを必要とします。

OSと初期アプリは、使用可能なRAMを断片化する読み込み中にビットとピースを割り当てる傾向があります。連続したブロックが使用できない場合、SUN JDKはそれを使用できません。BeaのJRockit(Oracleが買収)は、断片からメモリを割り当てることができます。


1

誰もが連続した記憶について答えているようですが、より差し迫った問題を認めることを怠っています。

100%の連続したメモリ割り当てがあっても、32ビットのWindows OSで2 GiBのヒープサイズを使用することはできません(デフォルトでは*)。これは、32ビットのWindowsプロセスが2 GiBを超える領域をアドレス指定できないためです。

Javaプロセスには、ヒープに加えて、 perm gen(Java 8より前)、スレッドごとのスタックサイズ、JVM /ライブラリのオーバーヘッド(ビルドごとにかなり増加します)がすべて含まれます

さらに、JVMフラグとそのデフォルト値はバージョン間で異なります。以下を実行するだけで、いくつかのアイデアが得られます。

 java -XX:+PrintFlagsFinal

オプションの多くは、ヒープ内外のメモリ分割に影響します。その2 GiBを多かれ少なかれ遊ばせる...

私のこの答えの一部を再利用するには(Tomcatについてですが、すべてのJavaプロセスに適用されます):

Windows OSは、32ビットプロセスのメモリ割り当てを合計2 GiBに制限します(デフォルト)。

プロセスに割り当てられている他のメモリ(JVM /ライブラリのオーバーヘッド、perm genスペースなど)もあるため、約1.5 GiBのヒープスペースを割り当てることができます。

32ビットWindowsが2 GBのプロセスアドレススペース制限を課すのに、64ビットWindowsは4 GB制限を課すのはなぜですか?

他の最近のオペレーティングシステム[咳Linux]では、32ビットプロセスが4 GiBのアドレス可能なスペースのすべて(またはほとんど)を使用できます。

つまり、32ビットプロセスの制限を4 GiB(32ビットでは3 GiB)に増やすように64ビットWindows OSを構成できます。

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx


1
この答えは、なぜ彼が2 GBしか割り当てられないのか、1つのコンピューターに1.4 GBを割り当て、別のコンピューターに1.2 GBしか割り当てられないのはなぜかを示しています。ここに記載されている1.5 GB、2 GB、4 GBの制限には達していません。
vapcguy 2017年

1
JVMフラグに関する段落は、メモリがバージョン間で異なる可能性がある理由を説明する方法の1つです。また、ヒープ設定が常にプロセス全体のサイズの(大きい)割合であるという点に注意してください。これを下回る設定でも、2 GiBのプロセス制限に達する可能性があります。別の設定は、連続するメモリ割り当てによって制約を受ける可能性があります。
Michael

あるいは、1.5 GBの制限、その1.4 GBの割り当てについて。今ではもっと理にかなっています-その説明に感謝します。
vapcguy 2017年

0

ページングサイズを増やす方法は次のとおりです

  1. mycomputer ---> properties ---> Advancedを右クリックします
  2. パフォーマンスセクションで設定をクリックします
  3. 「詳細」タブをクリックします
  4. [仮想メモリ]セクションで、[変更]をクリックします。現在のページングサイズが表示されます。
  5. HDDスペースが利用可能なドライブを選択します。
  6. 初期サイズと最大サイズを指定します...たとえば、初期サイズ0 MBと最大サイズ4000 MB。(必要なだけ)

0

**ヒープサイズを変更する方法は多数あります。

  1. file-> setting-> build、exceution、deployment-> compiler ここにヒープサイズがあります
  2. file-> setting-> build、exceution、deployment-> compiler-> andriodここにもヒープサイズがあります。同じ問題に直面している場合は、これをandriodプロジェクトで参照できます。

私のために働いたのは

  1. Javaが更新された場合に備えて、適切な適切なJAVA_HOMEパスを設定します。

  2. 新しいシステム変数を作成しますcomputer-> properties-> advanced setting- > create new system variable

名前:_JAVA_OPTION値:-Xmx750m

参考:Intellij ヘルプ->カスタムVMオプションの編集でデフォルトのVMオプションを見つけることができます 。このファイルには、ヒープの最小サイズと最大サイズが表示されます。**


-1

まず、4 GBのRAMがあるときにページファイルを使用しても意味がありません。Windowsは4GBを超えてアクセスすることはできず(実際には、メモリホールのために少ない)、ページファイルは使用されません。

第2に、アドレス空間は2つに分割され、半分はカーネル用、半分はユーザーモード用です。アプリケーション用により多くのRAMが必要な場合は、boot.iniで/ 3GBオプションを使用してください(java.exeが「大規模アドレス認識」としてマークされていることを確認してください(詳細はgoogle)。

3つ目は、javaが内部的に(スレッド、JITコンパイラ、VM初期化などのために)一部のメモリを浪費するため、2 GBのアドレス空間全体を割り当てることはできないと思います。詳細については、/ 3GBスイッチを使用してください。


1
4GBまたはRAMではページファイルが役に立たないという考えは間違っています。ページファイルがないと、オペレーティングシステムは物理RAMから未使用のプロセスデータ(未使用のサービス用のスタックスペースなど)を追い出すことができないため、実際の作業に使用できるRAMの量を減らすことができます。ページファイルがあると、RAMが解放されます。
誰も
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.