圧縮されたoopsでは、32GBのRAMしか使用できないことを理解できました。どういうわけか、2つのヒープなどを割り当てることで、それ以上の使用が可能ですか?
ありがとうヴィニート
圧縮されたoopsでは、32GBのRAMしか使用できないことを理解できました。どういうわけか、2つのヒープなどを割り当てることで、それ以上の使用が可能ですか?
ありがとうヴィニート
複数のヒープを持つことはできません(ただし、複数のJVMを持つことはできます。これは、スケールアップではなくスケールアウトと呼ばれます)。
JVMは、32GiBのメモリより下の圧縮オブジェクトポインタを自動的に使用します。それがどのように機能するかを理解している場合(メモリアライメントのために常に0であるため、各アドレスから最も若い3ビットを削除します)、それ以上進むことはできないことを理解します。
興味深い事実があります。この32GiB境界を超えると、JVMは圧縮オブジェクトポインタの使用を停止し、使用可能なメモリを効果的に削減します。つまり、JVMヒープを32 GiBを超えて増やすには、はるかに上に行く必要があります。JVMパフォーマンスチューニング@twitter(13:00頃)のプレゼンテーションについて私がこれまでに学んだすべてのことによると、ヒープを32GiBから48GiB未満に増やすと、圧縮されたオブジェクトポインターが存在しなくなるため、実際に使用可能なメモリの量(!)が減少します。
32 GBを超える容量が必要な場合は、オフヒープメモリの使用を検討することをお勧めします。これにより、ヒープをあまり消費しない追加のメモリスペースが効果的に提供されます。
たとえば、私は日常的に200〜800 GBを使用していますが、ヒープは1〜2GBだけです。これは、私が最も効率的な形式の圧縮されたOopsと事実上無制限の容量を持っていることを意味します。注:圧縮されたOopsには3つの形式があります。
オフヒープメモリを使用する2つの方法は、ダイレクトメモリByteBuffersとメモリマップトファイルです。ダイレクトメモリは、メインメモリサイズの約3/4まで十分に拡張できます。メモリマップトファイルは、ハードドライブの容量(通常ははるかに大きい)のサイズに合わせて拡張できます。
ここでは、実際のデータではなく参照によってスペースの80%が消費されるように、多くの最適化を適用しました。
これは、最も効率的なデータ構造を使用していないようです。データが使用されるスペースの多く、または少なくとも3分の2である場合は、さまざまなデータ構造を使用できます。
追加のパラメーターを使用して、より大きなヒープサイズを使用できます。
-XX:ObjectAlignmentInBytes=alignment
このパラメータは、Javaオブジェクトの固定調整です。デフォルト値は8
(バイト)です。示される値は2の累乗である必要があり、範囲はから8
です256
。
バイト単位のヒープサイズ制限は、次のように計算されます。
4GB * ObjectAlignmentInBytes
次の行を使用すると、圧縮ポインターに64GBのヒープサイズが使用可能になります。
-XX:ObjectAlignmentInBytes=16
ただし、ヒープサイズが大きい場合は、ドキュメントで考慮すべき注意事項があります。
注:配置値が増加すると、オブジェクト間の未使用スペースも増加します。その結果、Javaヒープサイズが大きい圧縮ポインターを使用してもメリットが得られない場合があります。
データの性質は正確には何ですか?
これを行う方法は、Javaヒープからデータを格納することかもしれません。これを行うには、通常はダイレクトByteBuffer
を使用してオフヒープメモリを取得し、データをバイト形式で格納します。これにはさまざまな利点があります。オブジェクトは非常にコンパクトに格納でき、大きなヒープを用意する必要はなく、オブジェクトがガベージコレクターによってスイープされることもありません。欠点は、複雑さとメモリリークのリスクです。
これを行うのに役立つライブラリがあります。
私があなたの立場にあった場合、私は次のそれぞれを調査します:
上記のそれぞれはあなたの問題を解決する可能性を秘めています。どちらが最も適切かは、私たちが言うのは本当に難しいです。
スペースの80%は、実際のデータではなく参照によって消費されます。
これはかなり極端に聞こえます。オブジェクト参照の数を減らすことに重点を置いて、データ構造を再検討する価値があるかもしれません。私は過去にこれらの方針に沿って物事を行ってきましたが、問題と現在使用しているデータ構造を知らずに具体的な推奨事項を提示することは非常に困難です。