POJO 形式の代わりにバイト配列でマップに値を保管することができます。そうすると、大きなオブジェクト・グラフが消費する可能性のあるメモリー占有スペースが減ります。
オブジェクト・グラフ中のオブジェクト数が増えるのにしたがって、 メモリー消費量は増加します。 複雑なオブジェクト・グラフを縮小して 1 つのバイト配列にすることによって、 いくつかのオブジェクトの代わりに、1 つだけのオブジェクトがヒープ内に保持されるようになります。このようにヒープ内の オブジェクト数が減ることで、Java ランタイムがガーベッジ・コレクション 中に検索するオブジェクトが少なくなります。
WebSphere® eXtreme Scale が使用するデフォルトのコピー・メカニズムは、 シリアライゼーションであり、これは高コストの処理です。例えば、デフォルトのコピー・モード COPY_ON_READ_AND_COMMIT を 使用している場合、読み取り時と取得時の両方でコピーが作成されます。バイト配列を使用すると、読み取り時にコピーを作成 する代わりに、値はバイトから送り込まれ、コミット時にコピーを作成する代わりに、 値はシリアライズされてバイトに入れられます。バイト配列を使用した結果、 データ整合性に関してはデフォルト設定と同等であり、使用メモリーは削減されます。
バイト配列を 使用する際は、メモリー消費量の削減を実現するには、最適化されたシリアライゼーション・メカニズムが 重要であることに注意してください。詳しくは、シリアライゼーション・パフォーマンスのチューニングを参照してください。
バイト配列マップを使用可能に するには、以下の例に示すように、ObjectGrid XML ファイルで、マップが使用する CopyMode 属性 の設定を COPY_TO_BYTES に変更します。
<backingMap name="byteMap" copyMode="COPY_TO_BYTES" />
特定のシナリオでバイト配列マップを 使用するかどうかは、よく検討する必要があります。バイト配列を使用すると、メモリー使用量は減らせますが、プロセッサー使用量は増える場合があります。
以下に、バイト配列マップ機能の使用を選択する前に検討する必要があるいくつかの要因の概略を示します。
オブジェクト・タイプ
オブジェクト・タイプによっては、バイト配列マップを 使用してもメモリー削減を期待できないものがあります。 つまり、バイト配列マップを使用するべきでない、いくつかのタイプのオブジェクトが あるということです。Java プリミティブ・ラッパーのいずれかを値として使用している場合、または、 他のオブジェクトへの参照を含んでいない (プリミティブ・フィールドのみを 保管する) POJO を 1 つ使用している場合、Java オブジェクトの 数は既に最小限になっていて、1 つしかありません。オブジェクトが使用するメモリー量は既に最適化されている ので、バイト配列マップをこれらのタイプのオブジェクトに使用することは お勧めしません。バイト配列マップが適している のは、POJO オブジェクト総数が 1 より大きい、他のオブジェクトまたはオブジェクトのコレクション を含んでいるオブジェクト・タイプです。
例えば、顧客オブジェクトが職場住所と自宅住所を 1 つずつ 含んでいて、さらに、注文のコレクションも含んでいる場合、 バイト配列マップの使用によって、ヒープ内のオブジェクト数と、これらのオブジェクトが使用するバイト数を 減らすことができます。
ローカル・アクセス
その他のコピー・モードを使用する際、コピーが作成されているとき (オブジェクトがデフォルトの ObjectTransformer により Cloneable である場合)、または最適化された copyValue メソッドがカスタム ObjectTransformer に提供されているときに、アプリケーションを最適化できます。他のコピー・モードと比べて、オブジェクトにローカルでアクセスする場合、読み取り、書き込み、またはコミット操作時のコピー作成で追加コストがかかります。例えば、分散トポロジーでニア・キャッシュがある場合、またはローカルまたはサーバーの ObjectGrid インスタンスに直接アクセスしている場合は、アクセスおよびコミットの時間は、バイト配列マップを使用すると、直列化のコストがかかるため増加します。同様のコストは、ObjectGridEventGroup.ShardEvents プラグイン使用時に、データ・グリッド・エージェントを 使用したり、サーバー・プライマリーにアクセスすると、分散トポロジーでも発生します。
プラグイン対話
バイト配列マップを使用すると、 クライアントからサーバーに通信しているときには、サーバーが POJO フォームを必要としない限りオブジェクトは インフレートされません。マップ値と対話するプラグインでは、 値をインフレートする要求が原因のパフォーマンス低下が起こります。
この追加コストは、LogElement.getCacheEntry または LogElement.getCurrentValue を使用 するすべてのプラグインで発生します。キーを取得したい場合は、LogElement.getKey を 使用すると、LogElement.getCacheEntry().getKey メソッドに関連した追加オーバーヘッドを 回避できます。以下のセクションでは、プラグインについて、バイト配列の使用を考慮に入れて 説明します。
索引および照会
オブジェクトが POJO 形式で保管されている 場合、オブジェクトをインフレートする必要がないので、索引付けおよび照会を実行するコストは 最小限ですみます。バイト配列マップを使用している場合、 オブジェクトをインフレートするための追加コストがかかります。一般的に、 アプリケーションが索引または照会を使用する場合は、 キー属性に対してのみ照会を実行するのでない場合は、バイト配列マップの使用は推奨されません。
オプティミスティック・ロック
オプティミスティック・ロック・ストラテジーを 使用している場合、更新操作および無効化操作中に追加コストがかかります。 これは、サーバー上の値をインフレートして、オプティミスティック衝突のチェックを行うための バージョン値を取得する必要があるためです。フェッチ操作を保証するためだけにオプティミスティック・ロックを 使用していて、オプティミスティック衝突のチェックは必要ない 場合、com.ibm.websphere.objectgrid.plugins.builtins.NoVersioningOptimisticCallback を 使用して、バージョン検査を使用不可にできます。
ローダー
ローダーを 使用している場合、値をインフレートしてから再シリアライズする操作をローダーが値を使用するときに行うため、eXtreme Scale ランタイムでもコストが かかります。それでも、ローダーと共にバイト配列マップを使用 することができますが、そのようなシナリオでは値に変更を加える ためのコストを考慮に入れる必要があります。例えば、ほとんどが読み取りのキャッシュ という状況でバイト配列機能を使用できます。この場合、 ヒープ内のオブジェクト数が少なく、使用されるメモリーも少ないという利点 のほうが、挿入および更新操作時にバイト配列の使用でコストが生じる というマイナス点を上回ります。
ObjectGridEventListener
ObjectGridEventListener プラグイン 内で transactionEnd メソッドを使用している場合、LogElement の CacheEntry または現行値 にアクセスするときのリモート要求に対する追加コストがサーバー・サイドで 生じます。このメソッドの実装がこれらのフィールドにアクセスしないようになっている 場合は、このような追加コストはありません。