質問

大量のヒープ領域を必要とする Java プログラムがあります。(他のコマンドライン引数の中でも特に) 最大ヒープ領域を 1500 MB に指定する引数 -Xmx1500m を使用してプログラムを開始します。新しく再起動した Windows XP ボックスでこのプログラムを起動すると、問題なく起動して実行されます。しかし、プログラムが数回実行されたり、コンピュータがしばらく起動していた場合など、起動しようとすると次のエラーが表示されます。

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

Windows 自体がメモリの断片化に悩まされているのではないかと考えていますが、この疑いを確認する方法がわかりません。この問題が発生した時点で、タスク マネージャーと sysinternals procexp は 2000MB の空きメモリを報告します。見てきました この質問は内部の断片化に関連しています

最初の質問は、自分の疑いをどのように確認すればよいでしょうか?2 番目の質問は、私の疑いが正しければ、この問題を解決するツールを知っている人はいますか?ということです。かなり調べてみましたが、マシンを定期的に再起動する以外に役立つものは見つかりませんでした。

ps - オペレーティング システムを変更することも、現時点では実行可能な選択肢ではありません。

役に立ちましたか?

解決

Torlack の意見に同意します。この原因の多くは、他の DLL が読み込まれて特定の場所に移動し、VM 用に取得できるメモリ量が 1 つの大きな塊に分割されるためです。

3G 以上のメモリがある場合は、Windows の一部を動かすために WinXP で作業を行うことができます。ここで PAE を検索してください。http://www.microsoft.com/whdc/system/platform/server/PAE/PAEdrv.mspx

Java アプリに本当に 1.2G 以上のメモリが必要な場合、64 ビット Windows、Linux、または OSX を検討するのが最善の策です。アプリで何らかのネイティブ ライブラリを使用している場合は、64 ビット用に再コンパイルする必要がありますが、32 ビット Windows で取得できるメモリを最大化するために DLL などをリベースするよりもはるかに簡単です。 。

もう 1 つのオプションは、プログラムを複数の VM に分割し、RMI やメッセージングなどを介して相互に通信させることです。こうすることで、各 VM に必要なメモリのサブセットを持たせることができます。アプリが何をするのかがわからないので、これが何らかの形で役立つかどうかはわかりませんが...

他のヒント

ページ ファイルのスペースが不足していない限り、この問題はコンピュータのメモリが不足していることではありません。仮想メモリの重要な点は、プロセスが物理的に利用可能な以上の仮想メモリを使用できるようにすることです。

JVM がヒープをどのように処理するかがわからないため、問題が何であるかを正確に言うのは少し難しいですが、一般的な問題の 1 つは、プロセス内にヒープを拡張できる十分な連続した空きアドレス空間がないことです。 。マシンがしばらく稼働した後になぜこれが問題になるのかは、少しわかりにくいです。

私は職場で同様の問題に取り組んでいます。WinDBG を使用してプログラムを実行し、「!address」コマンドと「!address -summary」コマンドを使用することが、プロセスの仮想アドレス空間が断片化した原因を追跡するのに非常に重要であることがわかりました。また、再起動後にプログラムを実行し、「!address」コマンドを使用してアドレス空間の写真を撮り、プログラムが実行されなくなったときに同じことを行うこともできます。これは問題の手がかりになるかもしれません。おそらく、追加の DLL の読み込みなどの単純な何かが問題を引き起こす可能性があります。

問題は Windows のメモリの断片化であると思われます。StackOverflow には別の質問があります。 Windows XP での Java 最大メモリ ここでは、Process Explorer を使用して DLL がメモリ内のどこにマップされているかを確認し、よりコンパクトな方法でメモリに読み込まれるように DLL をリベースすることで問題に対処することが記載されています。

Minimem の使用 (http://minimem.kerkia.net/) そのアプリケーションでは問題が解決する可能性があります。ただし、これがあなたが探している答えであるかどうかはわかりません。お役に立てれば幸いです。

たぶん、プログラムを開始し、メモリを予約し、各実行後にVMを終了しないことを検討する必要があります。さまざまな GC オプションを探して、オブジェクトを解放します。

Microsoft の SysInternals ツールの vmmap を使用して、仮想アドレス空間の断片化を表示し、空間を分割している原因を特定します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top