5.2. オフヒープメモリー
Data Grid は、キャッシュエントリーを、デフォルトで JVM ヒープメモリーに保存します。Data Grid は、オフヒープストレージを使用するように設定できます。つまり、データによって、管理された JVM メモリー領域外のネイティブメモリーに以下の利点があります。
- 同じデータ量に JVM ヒープメモリーよりも少ないメモリーを使用します。
- Garbage Collector (GC) の実行を回避するために、JVM 全体のパフォーマンスを改善できます。
しかし、オフヒープストレージにはトレードオフがあります。たとえば、JVM ヒープダンプには、オフヒープメモリーに保存されたエントリーは表示されません。
以下の図は、Data Grid が実行そている JVM プロセスのメモリー領域を示しています。
図5.1 JVM メモリー領域
JVM ヒープメモリー
ヒープは、参照される Java オブジェクトや他のアプリケーションデータをメモリーに維持するのに役立つ新しい世代と古い世代に分けられます。GC プロセスは、到達不能オブジェクトから領域を回収し、新しい生成メモリープールでより頻繁に実行します。
Data Grid がキャッシュエントリーを JVM ヒープメモリーに保存すると、キャッシュへのデータ追加を開始するため、GC の実行が完了するまで時間がかかる場合があります。GC は集中的なプロセスであるため、実行が長く頻繁になると、アプリケーションのパフォーマンスが低下する可能性があります。
オフヒープメモリー
オフヒープメモリーは、JVM メモリー管理以外のネイティブで利用可能なシステムメモリーです。JVM メモリーの領域 の図には、クラスメタデータを保持し、ネイティブメモリーから割り当てられる メタスペース メモリープールが表示されます。この図は、Data Grid キャッシュエントリーを保持するネイティブメモリーのセクションも含まれています。
データのオフヒープの保存
オフヒープキャッシュにエントリーを追加すると、Data Grid はネイティブメモリーをデータに動的に割り当てます。
Data Grid は、各キーのシリアル化された byte [] を、標準の Java HashMap と同様のバケットにハッシュ値を持ちます。バケットには、Data Grid がオフヒープメモリーに保存するエントリーの検索に使用するアドレスポインターが含まれます。
Data Grid は、オブジェクトインスタンスではなく、各オブジェクトのシリアライズされた byte[] 表現を使用して、オフヒープストレージで Java オブジェクトの等価性を決定します。
次の図は、名前付きのキーのセット、各キーのハッシュ、アドレスポインターのバケット配列、および名前と電話番号付きのエントリーを示しています。
図5.2 キー用のメモリーアドレスポインター
キーハッシュが衝突すると、データグリッドはエントリーをリンクします。William Clay と Luke Cage キーが同じハッシュを持っている場合、キーのメモリーアドレスポインター ダイアグラムで、その後、キャッシュに追加する最初のエントリーは、バケットの最初の要素です。
Data Grid はキャッシュエントリーをネイティブメモリーに保存する場合でも、ランタイム操作にはこれらのオブジェクトの JVM ヒープ表現が必要です。たとえば、cache.get() 操作は、返される前にオブジェクトをヒープメモリーに読み取ります。同様に、状態転送操作は、オブジェクトのサブセットが実行している間は、それらをヒープメモリーに保持します。
メモリーのオーバーヘッド
メモリーのオーバーヘッドは、Data Grid がエントリーを保存するために使用する追加のメモリーです。オフヒープストレージの場合、Data Grid はキャッシュの各エントリーに 25 バイトを使用します。
エビクションを使用して制限付きのオフヒープデータコンテナーを作成すると、Data Grid がキャッシュ内のエントリーを追跡してエビクションを実行するための追加のリンクリストを作成するため、メモリーオーバーヘッドが合計 61 バイトに増加します。
データの整合性
Data Grid は、ロックの配列を使用して、オフヒープアドレス空間を保護します。ロックの数は、コア数に 2 倍になり、その後に最も近い 2 の累乗に丸められます。これにより、書き込み操作が読み取り操作をブロックしないように、ReadWriteLock インスタンスの配分も存在します。
5.2.1. オフヒープメモリーの使用
JVM ヒープ領域以外のネイティブメモリーにキャッシュエントリーを保存するように Data Grid を設定します。
手順
オフヒープメモリーを使用するようにキャッシュ設定を変更します。
-
宣言型:
storage="OFF_HEAP"属性をmemory要素に追加します。 -
プログラム:
MemoryConfigurationBuilderクラスのstorage(OFF_HEAP)メソッドを呼び出します。
-
宣言型:
-
max-countまたはmax-sizeエビクションのいずれかを設定して、キャッシュが使用できるオフヒープメモリーの容量を制限します。
サイズがバインドされたオフヒープメモリー
宣言型設定
<distributed-cache name="off_heap" mode="SYNC">
<memory storage="OFF_HEAP"
max-size="1.5GB"
when-full="REMOVE"/>
</distributed-cache>
プログラムによる設定
ConfigurationBuilder cfg = new ConfigurationBuilder();
cfg
.memory()
.storage(StorageType.OFF_HEAP)
.maxSize("1.5GB")
.whenFull(EvictionStrategy.REMOVE)
.build());
エントリーの合計数によってバインドされているオフヒープメモリー
宣言型設定
<distributed-cache name="off_heap" mode="SYNC">
<memory storage="OFF_HEAP"
max-count="500"
when-full="REMOVE"/>
</distributed-cache>
プログラムによる設定
ConfigurationBuilder cfg = new ConfigurationBuilder();
cfg
.memory()
.storage(StorageType.OFF_HEAP)
.maxCount(500)
.whenFull(EvictionStrategy.REMOVE)
.build());