最近、JVMの内部について学びながら、これらの概念に出会いました。 SOについては、すでに個別に多くの質問があることは承知していますが、それらの関係や、単にそれらが何であるかを理解することはできません。
今私はそれらをそのように説明します:
ダイレクトメモリは、Java.nio.DirectByteBuffer
を使用してネイティブメモリを使用することを意味します。
ネイティブヒープは、unsafe.allocateMemory
を使用してネイティブメモリを使用するか、JNIコードでmalloc
を実行することを意味します。
オフヒープはネイティブメモリと同じです。
さらに1つの追加の質問として、JVMプロセス用に確保された合計メモリ空間(32ビットOSでは4GB)の外側にメモリを直接割り当てることは可能ですか?
私の理解の誤りを指摘し、可能であれば、それらについて明確に説明してください。
1)ヒープメモリ:JVMが管理するJVMプロセス内のメモリJavaオブジェクト
2)ネイティブメモリ/オフヒープ:ヒープ内にないプロセスアドレス空間内に割り当てられたメモリです。
3)ダイレクトメモリ:ネイティブに似ていますが、ハードウェア内の基本的なバッファーが共有されていることも意味します。たとえば、ネットワークアダプタまたはグラフィックディスプレイ内のバッファ。ここでの目標は、メモリ内で同じバイトがコピーされる回数を減らすことです。
最後に、OSに応じて、追加のネイティブ割り当て(メモリアドレススペースの割り当て)をUnsafe allocを介して、またはファイルのメモリマッピングによって実行できます。ファイルのメモリマッピングは、マシンが現在物理RAMとして持っているメモリよりも多くのメモリを簡単に割り当てることができるため、特に興味深いものです。また、合計アドレス空間の制限は、使用されているポインターのサイズによって制限され、32ビットポインターは4 GBを超えることはできません。限目。
jVMで実行される多くの高性能サーバーアプリケーションは、Apache Cassandraなどのサーバーのパフォーマンスを向上させるためにヒープ外メモリを使用します。ほとんどのデータ構造をヒープに格納するために使用されていましたが、最近のリリースでは、ヒープ以外のメモリに格納されていました
さらに1つの追加の質問として、JVMプロセス用に確保された合計メモリ空間(32ビットOSでは4GB)の外側にメモリを直接割り当てることは可能ですか?
4 GBは、32ビットOSでのプロセスの仮想アドレス空間の合計制限です。 4バイトのポインターは、それ以上のアドレスを指定することはできません。
あなたができる唯一のことは、大きなファイルを開いて、限られた量のメモリマップドバッファを介してそれとやり取りし、必要に応じてそれらをマッピングして解放し、OSページキャッシュがそれらを物理メモリに保持することを期待することです。
2GBを超えるメモリが必要な場合は、64ビットOSとJVMで実際に作業する必要があります。