JVMでメモリ割り当てがどのように機能するかを本当に理解したいと思っています。 Out of Memory:Heap Space exceptionsが発生するアプリケーションを作成しています。
JVMが実行中のプロセスに割り当てるヒープ領域を確保するために、XmsやXmxなどの引数をVMで渡すことができることを理解しています。これは、問題の解決策の1つです。メモリリークのための私のコードとそこの問題を修正します。
私の質問は:
1)JVMは実際にどのようにそれ自体にメモリを割り当てますか?これは、OSが利用可能なメモリをJVMに通信する方法とどのように関係しますか?または、より一般的には、プロセスのメモリ割り当ては実際にどのように機能しますか?
2)仮想メモリはどのように機能しますか? 32GBの物理メモリを備えたシステムがあり、32GBすべてをJavaプロセスに割り当てたとします。プロセスが実際に32GBのすべてのメモリを消費するとします。 OOM例外に遭遇する代わりに仮想メモリ?
ありがとう。
JVMは実際にどのようにメモリを自身に割り当てますか?
ヒープには、最大サイズのメモリの1つの大きな連続領域を割り当てます。最初はこれは仮想メモリですが、時間の経過とともに、OSの制御下で、使用される部分の実メモリになります
これは、OSが利用可能なメモリをJVMに通信する方法とどのように関係しますか?
JVMには、OSの空きメモリに関する情報がありません。
またはより一般的には、プロセスのメモリ割り当ては実際にどのように機能しますか?
一般的に、mallocとfreeを使用します。
仮想メモリはどのように機能しますか?
最初に仮想メモリが割り当てられ、これが使用されると実際のメモリに変わります。これはどのプロセスでも正常です。
32GBの物理メモリを備えたシステムがあり、32GBすべてをJavaプロセスに割り当てたとします。
できません。 OSにはメモリが必要であり、他の目的のためにメモリがあります。 JVM内でも、ヒープは使用されるメモリの一部にすぎません。 32 GBのメモリがある場合、最大24 GBのヒープを推奨します。
プロセスが実際に32GBのメモリをすべて消費するとします。
48 GBがあり、32 GBのメインメモリを使用するプロセスを開始するとします。
oOM例外に遭遇する代わりに仮想メモリを使用するようにプロセスを強制するにはどうすればよいですか?
アプリケーションは最初から仮想メモリを使用します。ヒープを大きくしすぎることはできません。ヒープがスワップを開始すると、アプリケーションだけでなくマシンも使用できなくなるからです。
オフヒープメモリを慎重に使用することにより、物理メモリよりも多くのメモリを使用できます。ただし、管理メモリは物理メモリ内にある必要があるため、32 GBのヒープが必要な場合は、64 GBのメインメモリを購入してください。
メモリを割り当てるJVM(または、そのプロセス)は、Cランタイムの ' malloc '関数を呼び出します。この関数は、Cランタイムのヒープメモリを維持します。次に、オペレーティングシステムカーネルからメモリを取得します。これに使用される機能はプラットフォームに依存します。 Linuxでは、 brkまたはsbrk システムコールを使用できます。
JVMがメモリを取得すると、メモリ自体を管理し、その一部を実行中のプログラムによって作成されたさまざまなオブジェクトに割り当てます。
仮想メモリは、オペレーティングシステムカーネルによって完全に処理されます。カーネルは、物理メモリページのさまざまなプロセスのアドレス空間へのマッピングを管理します。システム内のすべてのプロセスに必要な物理メモリよりも少ない物理メモリがある場合、OSカーネルはその一部をディスクにスワップアウトします。
プロセスに仮想メモリの使用を強制することはできません(必要ありません)。プロセスに対して透過的です。
「メモリ不足」エラーが発生している場合は、次の原因が考えられます。
JVMの制限を超えています。これらは、質問で述べたように、さまざまなコマンドライン引数および/またはプロパティによって制御されます
OSのスワップスペースが不足している可能性があります(または、開始するように構成されたスワップスペースがない)。または、一部のOSは仮想メモリさえサポートしていません。その場合、実メモリが不足しています。
ほとんどのOSには、管理者がプロセスによって消費されるメモリの量を制限する機能があります。たとえば、Linuxでは setrlimit システムコールやulimitシェルコマンド、あるいはその両方がカーネルの制限を設定します観察します。プロセスが制限で許可されているよりも多くのメモリを要求した場合、試行は失敗します(通常、これによりメモリ不足メッセージが表示されます)。
JVMはOSからJavaヒープメモリを割り当ててから、Javaアプリケーションのヒープを管理します。アプリケーションが新しいオブジェクトを作成すると、JVMはサブ割り当てを行います。他のオブジェクトによって参照されるヒープ内のオブジェクトは「ライブ」であり、参照され続ける限りヒープ内に残ります。参照されなくなったオブジェクトはガベージとJVMはヒープからクリアして、占有しているスペースを再利用できますJVMはガベージコレクション(GC)を実行してこれらのオブジェクトを削除し、ヒープに残っているオブジェクトを再編成します。
出典: http://pubs.vmware.com/vfabric52/index.jsp?topic=/com.vmware.vfabric.em4j.1.2/em4j/conf-heap-management.html
仮想メモリを使用するシステムでは、物理メモリは同じサイズのページに分割されます。プロセスによってアドレス指定されるメモリも、同じサイズの論理ページに分割されます。プロセスがメモリアドレスを参照すると、メモリマネージャは、参照されたアドレスを含むページをディスクからフェッチし、RAMの空いている物理ページに配置します。
ソース: http://searchstorage.techtarget.com/definition/virtual-memory
このブログでは、Javaメモリ使用率を参照します。
http://www.waratek.com/blog/november-2013/introduction-to-real-world-jvm-memory-utilisation