Java Platform, Standard Edition

HotSpot Virtual Machineガベージ・コレクション・チューニング・ガイド

リリース9

E90926-02(原本部品番号:E76294-05)

2017年10月

このガイドでは、Java HotSpot仮想マシン(Java HotSpot VM)に含まれる各種ガベージ・コレクション方式について説明しているので、ユーザーのニーズに応じた最適な方式の選定に役立ちます。

Java Platform, Standard Edition HotSpot仮想マシン・ガベージ・コレクション・チューニング・ガイド, リリース9

E90926-02

Copyright © 2014, 2017, Oracle and/or its affiliates.  All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。適用されるお客様とOracle Corporationとの間の契約に別段の定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。適用されるお客様とOracle Corporationとの間の契約に定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

目次

タイトルおよび著作権情報

はじめに

- 対象読者

- ドキュメントのアクセシビリティについて

- 関連ドキュメント

- 表記規則

1 ガベージ・コレクションのチューニングの概要

- ガベージ・コレクタとは

- ガベージ・コレクタの選択が問題になる理由

- ドキュメントでサポートされているオペレーティング・システム

2 エルゴノミクス

- ガベージ・コレクタ、ヒープおよびランタイム・コンパイラのデフォルト選択

- 動作ベースのチューニング

- 最大一時停止時間目標

- スループット目標

- フットプリント

- チューニング方法

3 ガベージ・コレクタの実装

- 世代別ガベージ・コレクション

- 世代

- パフォーマンスに関する考慮事項

- スループットおよびフットプリントの測定

4 ガベージ・コレクションのパフォーマンスに影響する要因

- ヒープの合計サイズ

- 世代サイズに影響するヒープ・オプション

- ヒープ・サイズのデフォルト・オプションの値

- Javaヒープ・サイズの最小化による動的フットプリントの節約

- 若い世代

- 若い世代のサイズ・オプション

- Survivor領域のサイズ設定

5 使用可能なコレクタ

- シリアル・コレクタ

- パラレル・コレクタ

- モーストリ・コンカレント・コレクタ

- コレクタの選択

6 パラレル・コレクタ

- パラレル・コレクタのガベージ・コレクタのスレッド数

- パラレル・コレクタでの世代の配置

- パラレル・コレクタ・エルゴノミクス

- パラレル・コレクタの動作を指定するオプション

- パラレル・コレクタの目標の優先度

- パラレル・コレクタの世代サイズの調整

- パラレル・コレクタのデフォルト・ヒープ・サイズ

- パラレル・コレクタのヒープ・サイズの初期値と最大値の指定

- 過剰なパラレル・コレクタ時間とOutOfMemoryError

- パラレル・コレクタの測定

7 モーストリ・コンカレント・コレクタ

- モーストリ・コンカレント・コレクタのオーバーヘッド

8 コンカレント・マーク・スイープ(CMS)コレクタ

- コンカレント・マーク・スイープ・コレクタのパフォーマンスと構造

- 並行モードの失敗

- 過剰なGC時間とOutOfMemoryError

- コンカレント・マーク・スイープ・コレクタとフローティング・ガベージ

- コンカレント・マーク・スイープ・コレクタの一時停止

- コンカレント・マーク・スイープ・コレクタのコンカレント・フェーズ

- コンカレント・コレクション・サイクルの開始

- 一時停止のスケジューリング

- コンカレント・マーク・スイープ・コレクタの測定

9 ガベージファースト・ガベージ・コレクタ

- ガベージファースト・ガベージ・コレクタの概要

- G1の有効化

- 基本概念

- ヒープ・レイアウト

- ガベージ・コレクション・サイクル

- ガベージファーストの内部

- 開始ヒープ占有率の決定

- マーキング

- 非常にタイトなヒープの状況における動作

- 大型オブジェクト

- 若い世代のみのフェーズの世代のサイズ設定

- 領域回収フェーズの世代のサイズ設定

- G1 GCのエルゴノミック・デフォルト

- 他のコレクタとの比較

10 ガベージファースト・ガベージ・コレクタのチューニング

- G1の一般的な推奨事項

- 他のコレクタからG1への移行

- G1パフォーマンスの向上

- フル・ガベージ・コレクションの監視

- 大型オブジェクトの断片化

- レイテンシのためのチューニング

- 通常と異なるシステムまたはリアル・タイムの使用状況

- 処理に長時間かかる参照オブジェクト

- 時間がかかりすぎる若い世代のみのコレクション

- 時間がかかりすぎる混合コレクション

- 高いRSの更新およびRSのスキャン時間

- スループットのためのチューニング

- ヒープ・サイズのためのチューニング

- チューニング可能なデフォルト設定

11 その他の考慮事項

- ファイナライズと弱参照、ソフト参照およびファントム参照

- 明示的なガベージ・コレクション

- ソフト参照

- クラス・メタデータ

はじめに

Java Platform, Standard Edition HotSpot仮想マシンのガベージ・コレクション・チューニング・ガイドでは、Java HotSpot仮想マシン(Java HotSpot VM)に含まれる各種ガベージ・コレクション方式について説明しているので、ユーザーのニーズに応じた最適な方式の選定に役立ちます。

対象読者

このドキュメントは、Java HotSpot VMガベージ・コレクタについての理解を深める必要がある、Java HotSpot VMのユーザー、アプリケーション開発者およびシステム管理者を対象としています。さらに、このドキュメントは、アプリケーションがユーザーの要件を満たすように、ガベージ・コレクションとの共通の問題の分析とソリューションに関する支援を提供しています。

ドキュメントのアクセシビリティについて

Oracleのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイト(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc)を参照してください。

Oracleサポートへのアクセス

サポートを購入したオラクル社のお客様は、My Oracle Supportを介して電子的なサポートにアクセスできます。詳細情報はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=infoか、聴覚に障害のあるお客様はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=trsを参照してください。

関連ドキュメント

詳細は、以下のドキュメントを参照してください。

- ガベージ・コレクション: 自動動的メモリー管理のアルゴリズム。Wiley、Chichester、1996年7月。(分散ガベージ・コレクションに関する章を含む)著者: R.Lins.Richard Jones、Anony Hosking,およびElliot Moss。

- ガベージ・コレクション・ハンドブック: 自動メモリー管理の技術。CRC適用アルゴリズムとデータ構造。ChapmanおよびHall、2012年1月

表記規則

このマニュアルでは次の表記規則を使用します。

表記規則

意味

太字

太字は、操作に関連するGraphical User Interface要素、または本文中で定義されている用語および用語集に記載されている用語を示します。

イタリック

イタリックは、ユーザーが特定の値を指定するプレースホルダ変数を示します。

固定幅フォント

固定幅フォントは、段落内のコマンド、URL、サンプル内のコード、画面に表示されるテキスト、または入力するテキストを示します。

1 ガベージ・コレクションのチューニングの概要

Java Platform, Standard Edition (Java SE)は、デスクトップで使用される小さなアプレットから大規模なサーバーで運用されるWebサービスまで、様々なアプリケーションで使用されています。Java HotSpot VMは、このように多様なデプロイメントに対応して、それぞれ異なる要件を満たすように設計された複数のガベージ・コレクタを備えています。Java SEは、アプリケーションが動作するコンピュータの種類に基づいて、最適なガベージ・コレクタを選択します。ただし、すべてのアプリケーションに対して最適な選択になるとはかぎりません。厳しいパフォーマンス目標などの要件が課せられたユーザー、開発者および管理者は、必要なレベルのパフォーマンスを達成するため、場合によってはガベージ・コレクタを明示的に選択して、特定のパラメータを調整する必要があります。このドキュメントでは、これらのタスクに役立つ情報を提供します。

最初に、stop-the-world型のシリアル・コレクタに関連する項で、ガベージ・コレクタの一般的な機能と基本的なチューニング・オプションについて説明します。次に、その他のコレクタ固有の機能について、コレクタの選択時に考慮すべき要因とともに紹介します。

トピック

- ガベージ・コレクタとは

- ガベージ・コレクタの選択が問題になる理由

- ドキュメントでサポートされているオペレーティング・システム

ガベージ・コレクタとは

ガベージ・コレクタ(GC)は、アプリケーションの動的メモリー割当てリクエストを自動的に管理します。

ガベージ・コレクションは、次の操作によって自動動的メモリー管理を実行します。

- オペレーティング・システムからメモリーを割り当てたり、メモリーを戻したりします。

- アプリケーションのリクエストに応じて、メモリーをアプリケーションに渡します。

- そのメモリーのどの部分がアプリケーションで使用されているかを判定します。

- 未使用のメモリーをアプリケーションで再使用するために回収します。

Java HotSpotガベージ・コレクションでは、様々な技術を採用して、これらの操作の効率性を改善します。

- 世代別のスカベンジをエージングとともに使用して、再利用可能で大きなメモリー領域が含まれている可能性のあるヒープ内の領域に集中します。

- 複数のスレッドを使用して、並列操作をアグレッシブに実行するか、アプリケーションと同時にバックグラウンドで長時間かかる操作を実行します。

- ライブ・オブジェクトを圧縮することで、連続的な大きな空きメモリーのリカバリを試行します。

ガベージ・コレクタの選択が問題になる理由

ガベージ・コレクタの目的は、手動の動的メモリー管理からアプリケーション開発者を解放することです。開発者は、割当てと割当て解除を照合し、割り当てられた動的メモリーの寿命を注意深く管理する必要性から解放されます。これにより、実行時に追加のオーバーヘッドを費やしていたメモリー管理に関連する、ある種類のエラーが完全になくなります。Java HotSpot VMでは、ガベージ・コレクションのアルゴリズムの選択肢を提供します。

ガベージ・コレクタの選択は、どのような場合に問題になるのでしょうか。アプリケーションによっては、まったく問題になりません。つまり、ガベージ・コレクションによる一時停止が適度な頻度で適度な期間にわたって発生すれば、アプリケーションは問題なく実行できます。ただし、大規模なアプリケーション、特に大量のデータ(複数GB)を保持し、多数のスレッドを使用する、トランザクション率の高いアプリケーションでは、このようにはいきません。

アムダールの法則(特定の問題に対して並列化がもたらす速度の向上は、問題の逐次処理部分によって制限される)は、ワークロードのほとんどは完全には並列化できず、必ず逐次処理される部分があり、その部分は並列処理の恩恵を受けないことを示しています。Javaプラットフォームでは、現在、4つのガベージ・コレクションの代替方法がサポートされていますが、そのうちの1つはシリアルGCで、それ以外のすべては作業を並列化してパフォーマンスを向上させます。ガベージ・コレクションのオーバーヘッドをできるだけ低くすることが重要です。次に例を示します。

図1-1のグラフは、ガベージ・コレクションを除いて、拡張性の高い理想的なシステムをモデルにしています。赤色の線は、単一プロセッサ・システムではガベージ・コレクションにわずか1%の時間しかかからないアプリケーションを示しています。この場合、32個のプロセッサを搭載したシステムでは、スループットは20%を超えて低下します。赤紫色の線はガベージ・コレクションに10%の時間がかかるアプリケーション(単一プロセッサ・アプリケーションでガベージ・コレクションに費やされる時間としてあり得ない値ではありません)を示し、プロセッサを32個に拡張したときのスループットは75%を超えて低下してしまいます。

図1-1 ガベージ・コレクションに要した時間の割合の比較

この図から、小規模なシステムの開発では無視できるスループットの問題が、大規模なシステムへと拡張すると重要なボトルネックになる可能性があることがわかります。ただし、このようなボトルネックを減らすように少し改善するだけで、パフォーマンスが大きく向上する可能性があります。十分に大規模なシステムでは、適切なガベージ・コレクタを選択し、必要に応じてチューニングする価値が大いにあります。

シリアル・コレクタは一般に、特に最新のプロセッサ上で、必要なヒープが最大でも100MB程度の小規模アプリケーションのほとんどに適しています。他のコレクタは、特殊な動作の代償として、オーバーヘッドや複雑さが増加します。他のコレクタが備える特殊な動作をアプリケーションが必要としない場合には、シリアル・コレクタを使用します。シリアル・コレクタが最適な選択肢にならないのは、大容量のメモリーと2個以上のプロセッサを搭載したマシンで動作する、スレッド化の程度が非常に高い大規模なアプリケーションの場合です。アプリケーションがserver-classマシンで実行されている場合、ガベージファースト(G1)・コレクタがデフォルトで選択されます。「エルゴノミクス」を参照してください。

ドキュメントでサポートされているオペレーティング・システム

このドキュメントおよびここでの推奨事項は、JDK 9でサポートされているすべてのシステム構成に当てはまりますが、特定の構成の一部のガベージ・コレクションの実際の可用性には制限があります。Oracle JDK 9およびJRE 9の認定システムの構成を参照してください。

2 エルゴノミクス

エルゴノミクスは、Java仮想マシン(JVM)およびガベージ・コレクションのヒューリスティック(動作ベースのヒューリスティックなど)でアプリケーションのパフォーマンスを向上させるために使用するプロセスです。

JVMでは、ガベージ・コレクタ、ヒープ・サイズおよびランタイム・コンパイラのデフォルト選択がプラットフォームごとに異なります。これらの選択は、コマンド行でのチューニングをあまり必要とせずに、各種アプリケーションのニーズに対応します。さらに、動作ベースのチューニングでは、アプリケーションの特定の動作にあわせてヒープ・サイズを動的に最適化します。

この項では、このようなデフォルト選択と動作ベースのチューニングについて説明します。これらのデフォルトを試してから、後続の項で説明している詳細な制御を使用してください。

トピック

- ガベージ・コレクタ、ヒープおよびランタイム・コンパイラのデフォルト選択

- 動作ベースのチューニング

- 最大一時停止時間目標

- スループット目標

- フットプリント

- チューニング方法

ガベージ・コレクタ、ヒープおよびランタイム・コンパイラのデフォルト選択

次に、ガベージ・コレクタ、ヒープ・サイズおよびランタイム・コンパイラのデフォルト選択に関する情報を示します。

server-classマシンと呼ばれるクラスのマシンは、次を搭載したマシンとして定義されています。

- 2個以上の物理プロセッサ

- 2GB以上の物理メモリー

server-classマシンでは、次がデフォルトで選択されています。

- ガベージファースト(G1)・コレクタ

- 初期ヒープ・サイズ: 物理メモリーの1/64

- 最大ヒープ・サイズ: 物理メモリーの1/4

- C1とC2の両方を使用する階層型コンパイラ

動作ベースのチューニング

Java HotSpot VMガベージ・コレクションは、最大一時停止時間とアプリケーション・スループットの2つの目標のいずれかを優先的に満たすように構成できます。優先する目標に達した場合、コレクタはもう一方の目標を最大化しようとします。通常、これらの目標は必ずしも満たせるとはかぎりません。アプリケーションは少なくともすべてのライブ・データを維持するのに最小限のヒープが必要であり、他の構成では一部またはすべての必要な目標に到達しないようにできます。

最大一時停止時間目標

一時停止時間とは、ガベージ・コレクタがアプリケーションを停止して、使用されなくなった領域をリカバリする期間のことです。最大一時停止時間目標は、このような一時停止の最長時間を制限することが目的です。

平均一時停止時間とその平均の偏差はガベージ・コレクタによって保持されます。平均は実行開始時から計算されますが、最近の一時停止ほど重み付けが大きくなるように加重されます。平均一時停止時間とその偏差の合計が最大一時停止時間目標を超えると、ガベージ・コレクタは目標が達成されていないとみなします。

最大一時停止時間目標は、コマンド行オプション-XX:MaxGCPauseMillis=<nnn>で指定します。これは、<nnn>ミリ秒以下の一時停止時間が望ましいという、ガベージ・コレクタへのヒントとして解釈されます。ガベージ・コレクタでは、ガベージ・コレクションによる一時停止を<nnn>ミリ秒未満に維持するように、Javaヒープ・サイズや他のガベージ・コレクション関連パラメータを調整します。最大一時停止時間目標のデフォルト設定は、コレクタによって異なります。このような調整により、ガベージ・コレクションの発生頻度が増え、アプリケーションの全体的なスループットが低下する可能性があります。場合によっては、望ましい一時停止時間目標を満たせないことがあります。

スループット目標

スループット目標はガベージの収集に消費された時間の観点から測定され、ガベージ・コレクション以外で消費された時間はアプリケーション時間となります。

この目標は、コマンド行オプション-XX:GCTimeRatio=nnnで指定します。ガベージ・コレクション時間のアプリケーション時間に対する比率は1 / (1+nnn)です。たとえば、-XX:GCTimeRatio=19は、ガベージ・コレクションに合計時間の20分の1 (5%)という目標を設定します。

ガベージ・コレクションで消費される時間は、一時停止を含むすべてのガベージ・コレクションを合計した時間です。スループット目標が満たされていない場合、ガベージ・コレクタに想定される処理は、コレクションの一時停止と一時停止の間にアプリケーションで費やされる時間を長くするようにヒープ・サイズを増やすことです。

フットプリント

スループット目標と最大一時停止時間目標が満たされている場合、ガベージ・コレクタはどちらかの目標(常にスループット目標)が満たされなくなるまで、ヒープ・サイズを小さくします。ガベージ・コレクタが使用できる最小および最大ヒープ・サイズは、最小および最大ヒープ・サイズにそれぞれ -Xms=<nnn>および-Xmx=<mmm>を使用して設定できます。

チューニング方法

ヒープは選択されたスループット目標に対応するサイズに拡大/縮小されます。最大ヒープ・サイズの選択および最大一時停止時間目標の選択などのヒープ・チューニング方法を確認します。

デフォルト最大ヒープ・サイズよりも大きいヒープが必要なことがわかっている場合を除いて、ヒープの最大値を選択しないでください。アプリケーションにとって十分なスループット目標を選択してください。

アプリケーションの動作に変更があると、ヒープが拡大/縮小される場合があります。たとえば、アプリケーションが高速な割当てを開始すると、ヒープは同じスループットを維持するために拡大します。

ヒープが最大サイズまで大きくなり、スループット目標が満たされていない場合は、最大ヒープ・サイズがスループット目標に対して小さすぎます。最大ヒープ・サイズをプラットフォームの総物理メモリーに近い値、ただしアプリケーションのスワッピングを引き起こさない程度に設定してください。アプリケーションを再実行します。それでもスループット目標を満たせない場合は、アプリケーション時間の目標がプラットフォームで使用可能なメモリーに対して高すぎます。

スループット目標は満たせるけれども、一時停止が長すぎる場合は、最大一時停止時間目標を選択します。最大一時停止時間目標を選択すると、スループット目標が満たされなくなる可能性があるので、アプリケーションにとって受け入れ可能な妥協値を選択してください。

ガベージ・コレクタでは相反する目標を満たそうとするので、ヒープ・サイズの変動はよくあることです。これは、アプリケーションが定常状態になった場合にも当てはまります。スループット目標(大きなヒープが必要)を達成しようとする圧力は、最大一時停止時間と最小フットプリントの目標(いずれも小さなヒープが必要)と相反します。

3 ガベージ・コレクタの実装

Java SEプラットフォームの強みの1つは、メモリー割当てとガベージ・コレクションの複雑さが開発者から隠蔽されることです。

ただし、ガベージ・コレクションが重要なボトルネックになった場合、実装面を理解しておくと役に立ちます。ガベージ・コレクタでは、アプリケーションがどのようにオブジェクトを使用するかについて前提を立て、それを調整可能なパラメータに反映して、これらのパラメータを調整することで、抽象化の威力を犠牲にすることなくパフォーマンスを改善できます。

トピック

- 世代別ガベージ・コレクション

- 世代

- パフォーマンスに関する考慮事項

- スループットおよびフットプリントの測定

世代別ガベージ・コレクション

実行中のプログラムで他のライブ・オブジェクトから参照されなくなると、オブジェクトはガベージ(廃棄物)とみなされ、そのメモリーはVMで再使用できるようになります。

理論上、最も簡単なガベージ・コレクション・アルゴリズムは、到達可能なすべてのオブジェクトを1つずつ実行するたびに調べます。残りのオブジェクトはガベージとみなされます。この方法ではライブ・オブジェクトの数に比例した時間がかかるので、大量のライブ・データが保持される大規模なアプリケーションでは使用できません。

Java HotSpot VMには様々な種類のガベージ・コレクション・アルゴリズムが組み込まれており、それらはすべて世代別コレクションと呼ばれる技術を使用しています。ネイティブ・ガベージ・コレクションでは常にヒープ内のすべてのライブ・オブジェクトを調べますが、世代別コレクションでは、ほとんどのアプリケーションで経験的に得られたいくつかの特徴を利用して、未使用(ガベージ)オブジェクトの回収に必要な作業を最小限に抑えます。このように得られた特徴の中で最も重要なのは弱い世代別仮説であり、この説では、ほとんどのオブジェクトは短命であることが示されています。

図3-1に青で示した領域が、オブジェクトの典型的な寿命分布です。X軸は、オブジェクトの寿命を、割り当てられたバイト数で示しています。Y軸のバイト数は、その寿命を持つオブジェクト群の総バイト数です。左端の鋭いピークは、割当て後にすぐに回収できる(「寿命を終えた」)オブジェクトを表しています。たとえば、イテレータ・オブジェクトは、1つのループ期間だけ生存するのが一般的です。

図3-1 オブジェクトの典型的な寿命分布

より寿命が長いオブジェクトもあるので、分布は右側に伸びています。たとえば、初期化時に割り当てられ、VMが終了するまで生き続けるオブジェクトはよくあります。この2種類の両極端なオブジェクトの中間に、なんらかの中間演算の間だけ生存するオブジェクトがあり、ここでは初期ピークの右側のこぶとして現れています。これとはまったく違う分布になるアプリケーションもありますが、驚くほど多くのアプリケーションで、この一般的な形状が当てはまります。オブジェクトの大半が「短命」であるという事実に着目すると、コレクションの効率化が可能になります。

世代

このシナリオを最大限に活用するのが、メモリーの世代(年齢ごとにオブジェクトを保持するメモリー・プール)別管理です。ある世代がいっぱいになったときに、その世代でガベージ・コレクションを実行します。

大半のオブジェクトは若いオブジェクト用のプール(若い世代)に割り当てられ、ほとんどのオブジェクトはそこで寿命を終えます。若い世代がいっぱいになると、マイナー・コレクションが発生して、若い世代のみが収集されます。他の世代のガベージは回収されません。このようなコレクションのコストは、一次的には、収集されるライブ・オブジェクトの数に比例します。寿命を終えたオブジェクトでいっぱいの若い世は非常にすばやく収集されます。一般に、各マイナー・コレクションで生き残ったオブジェクトの一部は若い世代から古い世代に移されます。最終的に古い世代がいっぱいになって収集が必要になると、メジャー・コレクションが発生し、ヒープ全体が収集されます。メジャー・コレクションは、非常に多くのオブジェクトを対象とするため、通常はマイナー・コレクションよりはるかに長い時間がかかります。図3-2に、シリアル・ガベージ・コレクタにおける世代のデフォルトの配置を示します。

図3-2 シリアル・コレクタにおける世代のデフォルトの配置

起動時に、Java HotSpot VMはアドレス空間にJavaヒープ全体を確保しますが、必要にならないかぎり、物理メモリーをこれに割り当てません。Javaヒープを対象とするアドレス空間全体は、論理的に若い世代と古い世代に分けられます。オブジェクト・メモリー用に確保されるアドレス空間全体は、若い世代と古い世代に分けることができます。

若い世代はEden領域と2つのSurvivor領域で構成されています。ほとんどのオブジェクトは最初にEdenに割り当てられます。Survivor領域の一方は常に空で、Eden内およびガベージ・コレクション時のもう一方のSurvivor領域のライブ・オブジェクトのコピー先として使用されます。ガベージ・コレクション後、Edenおよびコピー元のSurvivor領域は空です。次のガベージ・コレクションでは、2つのSurvivor領域の目的が交換されます。直近でいっぱいになった領域がライブ・オブジェクトのコピー元であり、もう一方のSurvivor領域にコピーされます。このようにして、そのオブジェクトが何回かコピーされるか、十分な領域がなくなるまで、Survivor領域間でオブジェクトがコピーされます。これらのオブジェクトは、古いリージョンにコピーされます。このプロセスはエージングとも呼ばれます。

パフォーマンスに関する考慮事項

ガベージ・コレクションで測定するのは、主にスループットとレイテンシです。

- スループットは、長期間で見たときの、ガベージ・コレクション以外の処理に使用される時間の割合です。スループットには割当てにかかる時間も含まれます(ただし、通常は割当ての速度を調整する必要はありません)。

- レイテンシはアプリケーションの応答性です。ガベージ・コレクションの一時停止は、アプリケーションの応答性に影響を及ぼします。

ガベージ・コレクションの要件は、ユーザーによって様々です。たとえば、ガベージ・コレクション中の一時停止は許容できるか、ネットワーク遅延の前では目立たないため、Webサーバーの適切なメトリックはスループットだと考えるユーザーもいます。これに対して、対話型のグラフィック・プログラムでは、ほんの短い一時停止でも、ユーザーの操作性を損う可能性があります。

これ以外のことを重視するユーザーもいます。フットプリントは、プロセスの作業セットをページ数やキャッシュ・ライン数で測定したものです。物理メモリーが制限されていたり、プロセス数が多いシステムでは、フットプリントがスケーラビリティを左右する可能性があります。機敏性は、オブジェクトが寿命を終えてから、そのメモリーが使用可能になるまでの時間で、Remote Method Invocation (RMI)などの分散システムでは、重要な考慮事項になります。

一般に、特定の世代のサイズを選択することは、これらの考慮事項とのトレードオフです。たとえば、若い世代を非常に大きくすると、スループットが最大になりますが、フットプリント、機敏性および一時停止時間が犠牲になります。若い世代を小さくすると、若い世代の一時停止を最小にできますが、スループットが犠牲になります。1つの世代のサイズを変更しても、別の世代のコレクションの頻度や一時停止時間には影響しません。

世代のサイズを選択する方法は1つではありません。アプリケーションによるメモリーの使用方法とユーザー要件によって、最適な選択が決まります。そのため、仮想マシンによるガベージ・コレクタの選択が必ずしも最適とはかぎらないので、コマンド行オプションを使用してオーバーライドできます(「ガベージ・コレクションのパフォーマンスに影響する要因」を参照)。

スループットおよびフットプリントの測定

スループットとフットプリントの最適な測定方法は、アプリケーション専用のメトリックスを使用するやり方です。

たとえば、Webサーバーのスループットはクライアント負荷生成プログラムを使用してテストでき、そのサーバーのフットプリントは、pmapコマンド(Solarisオペレーティング・システムの場合)を使用して測定できます。これに対して、ガベージ・コレクションによる一時停止は、仮想マシン自体の診断出力をチェックすることで簡単に推測できます。

コマンド行オプション-verbose:gcを使用すると、コレクションごとにヒープとガベージ・コレクションに関する情報が出力されます。次はその例です。

[15,651s][info ][gc] GC(36) Pause Young (G1 Evacuation Pause) 239M->57M(307M) (15,646s, 15,651s) 5,048ms
[16,162s][info ][gc] GC(37) Pause Young (G1 Evacuation Pause) 238M->57M(307M) (16,146s, 16,162s) 16,565ms
[16,367s][info ][gc] GC(38) Pause Full (System.gc()) 69M->31M(104M) (16,202s, 16,367s) 164,581ms

この出力では、2つの若いコレクションの後に、System.gc()への呼出しでフル・コレクションがアプリケーションによって開始されます。行の先頭は、アプリケーションが起動された時間を示すタイム・スタンプです。その次は、この行のログ・レベル(info)とタグ(gc)に関する情報です。この後に、GC識別番号が続きます。この場合、番号が36、37および38の3つのGCがあります。その後、GCのタイプとGCが起動された原因が記録されます。この後、メモリー消費に関する情報の一部が記録されます。このログで使用する形式は、"GC前の使用量" -> "GC後の使用量" ("ヒープ・サイズ")です。

この例の最初の行は、239M->57M(307M)となっています。これは、GCの前は239MBが使用されていて、GCでメモリーの大部分がクリーン・アップされ、57MBが残ったことを示します。ヒープ・サイズは307MBです。この例では、フルGCでヒープが307MBから104MBに縮小されていることに注意してください。メモリー使用量情報の後、GCの開始時間と終了時間が期間(終了 - 開始)とともに記録されます。

-verbose:gcコマンドは-Xlog:gcの別名です。-Xlogは、HotSpot JVMでのロギング用の一般的なロギング構成オプションです。これはタグベースのシステムであり、gcはタグの1つです。GCの実行内容に関する詳細情報を取得するには、gcタグと他のタグを含むメッセージを出力するようにロギングを構成します。これを実行するコマンド行オプションは、-Xlog:gc*です。

次に、-Xlog:gc*で記録されたG1の若いコレクションの一例を示します。

[10.178s][info][gc,start ] GC(36) Pause Young (G1 Evacuation Pause)
[10.178s][info][gc,task ] GC(36) Using 28 workers of 28 for evacuation
[10.191s][info][gc,phases ] GC(36) Pre Evacuate Collection Set: 0.0ms
[10.191s][info][gc,phases ] GC(36) Evacuate Collection Set: 6.9ms
[10.191s][info][gc,phases ] GC(36) Post Evacuate Collection Set: 5.9ms
[10.191s][info][gc,phases ] GC(36) Other: 0.2ms
[10.191s][info][gc,heap ] GC(36) Eden regions: 286->0(276)
[10.191s][info][gc,heap ] GC(36) Survivor regions: 15->26(38)
[10.191s][info][gc,heap ] GC(36) Old regions: 88->88
[10.191s][info][gc,heap ] GC(36) Humongous regions: 3->1
[10.191s][info][gc,metaspace ] GC(36) Metaspace: 8152K->8152K(1056768K)
[10.191s][info][gc ] GC(36) Pause Young (G1 Evacuation Pause) 391M->114M(508M) 13.075ms
[10.191s][info][gc,cpu ] GC(36) User=0.20s Sys=0.00s Real=0.01s

注意:
-Xlog:gc*によって生成される出力形式は、今後のリリースで変更されることがあります。

4 ガベージ・コレクションのパフォーマンスに影響する要因

ガベージ・コレクションのパフォーマンスに影響する最も重要な2つの要因は、使用可能なメモリー総量と若い世代用のヒープの割合です。

トピック

- ヒープの合計サイズ

- 世代サイズに影響するヒープ・オプション

- ヒープ・サイズのデフォルト・オプションの値

- Javaヒープ・サイズの最小化による動的フットプリントの節約

- 若い世代

- 若い世代のサイズ・オプション

- Survivor領域のサイズ設定

ヒープの合計サイズ

ガベージ・コレクションのパフォーマンスに影響する最も重要な要因は、使用可能なメモリーの総量です。コレクションは世代がいっぱいになると発生するので、スループットは使用可能なメモリーの量に反比例します。

注意:

次に示すヒープの拡大と縮小、ヒープ・レイアウトおよびデフォルト値に関する説明は、例としてシリアル・コレクタを使用しています。他のコレクタが同様のメカニズムを使用しても、ここで示される詳細は他のコレクタに当てはまらないことがあります。他のコレクタに関する同様の情報は、それぞれのトピックを参照してください。

世代サイズに影響するヒープ・オプション

世代サイズに影響するオプションはたくさんあります。図4-1は、ヒープ内のコミットされた領域と仮想領域の違いを示しています。仮想マシンの初期化時に、ヒープの全体領域が確保されます。確保する領域のサイズは、-Xmxオプションで指定できます。-Xmsパラメータの値が-Xmxパラメータの値よりも小さい場合、確保されている領域の一部がただちに仮想マシン用にコミットされます。この図では、コミットされていない領域は「Virtual」と示されています。ヒープのそれぞれの部分(古い世代と若い世代)は、必要に応じて、仮想領域の制限までサイズを大きくすることができます。

パラメータのいくつかは、ヒープのある部分と他の部分の比率です。たとえば、パラメータ–XX:NewRatioは、古い世代の若い世代に対する相対サイズを示します。

図4-1 ヒープ・オプション

ヒープ・サイズのデフォルト・オプションの値

デフォルトで、コレクションが発生するたびに、ライブ・オブジェクトに対する空き領域の割合が一定範囲内に保たれるように、仮想マシンによってヒープが拡大/縮小されます。

この対象範囲は-XX:MinHeapFreeRatio=<minimum>オプションと-XX:MaxHeapFreeRatio=<maximum>オプションでパーセント値として設定され、合計サイズは下限値–Xms<min>と上限値–Xmx<max>によって制限されます。64ビットSolarisオペレーティング・システム(SPARC Platform Edition)用のデフォルト・オプションを表4-1に示します。

表4-1 64ビットSolarisオペレーティング・システム用のデフォルト・オプション

オプション

デフォルト値

-XX:MinHeapFreeRatio

40

-XX:MaxHeapFreeRatio

70

-Xms

6656KB

-Xmx

計算

これらのオプションを使用した場合、世代の空き領域の割合が40%を下回ると、40%の空き領域を維持するように、世代の最大許容サイズを上回らない範囲で世代のサイズが拡大されます。同様に、空き領域の割合が70%を超えると、空き領域が70%以下になるように、世代の最小サイズを下回らない範囲で世代のサイズが縮小されます。

表4-1に示されているように、デフォルトの最大ヒープ・サイズはJVMで計算される値です。Java SEのパラレル・コレクタとサーバーJVMで使用されていた計算は、すべてのガベージ・コレクタで使用されるようになりました。64ビット・プラットフォームの最大ヒープ・サイズの上限の計算も含まれます。「パラレル・コレクタのデフォルト・ヒープ・サイズ」を参照してください。クライアントJVMにも同様の計算があり、サーバーJVMよりも最大ヒープ・サイズが小さくなります。

サーバー・アプリケーションのヒープ・サイズに関する一般的なガイドラインを次に示します。

- 一時停止が問題になっていなければ、できるだけ多くのメモリーを仮想マシンに割り当てます。多くの場合、デフォルトのサイズは小さすぎます。

- -Xmsと-Xmxを同じ値に設定すると、サイズについての最も重要な決断を仮想マシンが行う必要がなくなり、予測性が高まります。ただし、ユーザーの選択が不適切であった場合に、仮想マシンでは調整できません。

- 一般に、割当ては並列化できるので、プロセッサ数を増やすにつれて、メモリーも増やしてください。

Javaヒープ・サイズの最小化による動的フットプリントの節約

アプリケーション用の動的メモリー・フットプリント(実行中に消費される最大RAM)を最小化する必要がある場合、Javaヒープ・サイズを最小化することにより、これを実行できます。Java SE Embeddedアプリケーションは、これを行う必要があります。

Javaヒープ・サイズを最小化するには、コマンド行オプション-XX:MaxHeapFreeRatioおよび-XX:MinHeapFreeRatioを使用して、オプション-XX:MaxHeapFreeRatio (デフォルト値は70%)および-XX:MinHeapFreeRatio (デフォルト値は40%)の値を小さくします。-XX:MaxHeapFreeRatioを10%程度小さくして-XX:MinHeapFreeRatioを小さくすると、パフォーマンスが大幅に低下することなく、ヒープ・サイズが正常に削減されることが示されます。ただし、アプリケーションによって結果は異なることがあります。これらの値が可能なかぎり低くなり、許容できるパフォーマンスを維持するように、様々な値を試してください。

さらに、-XX:-ShrinkHeapInStepsを指定して、即座にJavaヒープをターゲット・サイズに削減することもできます(パラメータ-XX:MaxHeapFreeRatioにより指定)。これを設定すると、パフォーマンスが低下する場合があります。デフォルトでは、JavaランタイムでJavaヒープをターゲット・サイズに徐々に削減します。このプロセスには複数のガベージ・コレクション・サイクルが必要になります。

若い世代

使用可能なメモリー総量に次いで、ガベージ・コレクションのパフォーマンスに影響する重要な要因は、若い世代用のヒープの割合です。

若い世代のサイズが大きいほど、マイナー・コレクションが発生しにくくなります。ただし、ヒープのサイズには制限があるので、若い世代を大きくすると、古い世代が小さくなり、メジャー・コレクションが発生しやすくなります。最適な選択は、アプリケーションによって割り当てられるオブジェクトの寿命分布に左右されます。

若い世代のサイズ・オプション

デフォルトでは、若い世代のサイズはオプション-XX:NewRatioで制御します。

たとえば、-XX:NewRatio=3と設定すると、若い世代と古い世代の比率が1:3になります。つまり、Eden領域とSurvivor領域の合計サイズが、合計ヒープ・サイズの1/4になります。

オプション-XX:NewSizeと-XX:MaxNewSizeでは、若い世代の下限値と上限値を設定します。これらを同じ値に設定すると、若い世代のサイズが固定されます(-Xmsと-Xmxを同じ値にすると、合計ヒープ・サイズが固定されるのと同じです)。これは、-XX:NewRatioで許可されている整数倍よりもきめ細かく若い世代を調整できるので便利です。

Survivor領域のサイズ設定

オプション-XX:SurvivorRatioを使用すると、Survivor領域のサイズを調整できますが、これはパフォーマンスの点でそれほど重要にはなりません。

たとえば、-XX:SurvivorRatio=6と設定すると、Eden領域とSurvivor領域との比率が1:6になります。つまり、各Survivor領域のサイズはEden領域の1/6、すなわち若い世代の1/8になります(Survivor領域は2つあるので、1/7にはなりません)。

Survivor領域が小さすぎると、コピー方式コレクションがオーバーフローして、古い世代に直接送られてしまいます。Survivor領域が大きすぎると、使用されない領域が無駄になります。仮想マシンは、ガベージ・コレクションのたびに、しきい値(古い世代に送るまでにオブジェクトをコピーできる回数)を選択します。このしきい値は、Survivor領域の使用率を半分以下に抑えるように選択されます。このしきい値と、新しい世代のオブジェクトの年齢を表示するには、ログ構成-Xlog:gc,ageを使用できます。これは、アプリケーションの寿命分布を確認する場合にも役立ちます。

表4-2に64ビットSolarisのデフォルト値を指定します。

表4-2 Survivor領域のサイズ設定のデフォルト・オプション値

オプション

サーバーJVMのデフォルト値

-XX:NewRatio

2

-XX:NewSize

1310MB

-XX:MaxNewSize

無制限

-XX:SurvivorRatio

8

若い世代の最大サイズは、ヒープ総量の最大サイズと-XX:NewRatioパラメータの値から計算されます。-XX:MaxNewSizeパラメータのデフォルト値「無制限」は、コマンド行で-XX:MaxNewSizeに値を指定しないかぎり、計算値は-XX:MaxNewSizeで制限されないことを意味しています。

サーバー・アプリケーションの一般的なガイドラインを次に示します。

- 最初に、仮想マシンに割り当てる余裕のある最大ヒープ・サイズを決定します。次に、若い世代のサイズに対する独自のパフォーマンス・メトリックをグラフにして、最適な設定を求めます。

- 最大ヒープ・サイズは、マシンに搭載されたメモリー容量よりも必ず小さくして、過剰なページ・フォルトやスラッシングの発生を回避する必要があります。

- 合計ヒープ・サイズが固定されている場合、若い世代のサイズを増やすには、古い世代のサイズを減らす必要があります。アプリケーションによって一定期間使用されるすべてのライブ・データを保持するのに十分な大きさと、ある程度の余分な領域(10%から20%以上)を古い世代に確保します。

- 前に説明した古い世代の制約に従います。

- 十分な量のメモリーを若い世代に割り当てます。

- 割当ては並列化できるので、プロセッサ数を増やすにつれて、若い世代のサイズも大きくしてください。

5 使用可能なコレクタ

ここまでは、シリアル・コレクタについて説明してきました。Java HotSpot VMには3つの異なるタイプのコレクタがあり、それぞれパフォーマンス特性が異なります。

トピック

- シリアル・コレクタ

- パラレル・コレクタ

- モーストリ・コンカレント・コレクタ

- コレクタの選択

シリアル・コレクタ

シリアル・コレクタでは単一のスレッドを使用してすべてのガベージ・コレクション作業を実行するので、スレッド間通信のオーバーヘッドが発生しないため、比較的効率的です。

これはマルチプロセッサ・ハードウェアを活用できないので、シングル・プロセッサ・マシンに最適ですが、小規模なデータ・セット(最大で約100MB)を保持するアプリケーションに対しては、マルチプロセッサ上でも使用できる場合があります。シリアル・コレクタは、特定のハードウェアおよびオペレーティング・システム構成でデフォルト選択されていることもあれば、オプション-XX:+UseSerialGCで明示的に有効にすることもできます。

パラレル・コレクタ

パラレル・コレクタはスループット・コレクタとも呼ばれ、シリアル・コレクタと同様に世代別コレクタです。シリアル・コレクタとパラレル・コレクタとの主な違いは、パラレル・コレクタには複数のスレッドがあり、これを使用してガベージ・コレクションを高速化する点です。

パラレル・コレクタは、マルチプロセッサまたはマルチスレッド・ハードウェアで実行される、中規模から大規模サイズのデータ・セットを保持するアプリケーション向けです。これを有効にするには、-XX:+UseParallelGCオプションを使用します。

パラレル圧縮は、パラレル・コレクタがメジャー・コレクションを並列実行できるようにする機能です。パラレル圧縮が使用できないと、メジャー・コレクションは単一のスレッドを使用して実行されるので、可用性が大きく制限されます。オプション-XX:+UseParallelGCが指定されている場合、パラレル圧縮はデフォルトで有効です。これを無効にするには、-XX:-UseParallelOldGCオプションを使用します。

モーストリ・コンカレント・コレクタ

コンカレント・マーク・スイープ(CMS)コレクタおよびガベージファースト(G1)ガベージ・コレクタは、両方ともモーストリ・コンカレント・コレクタです。モーストリ・コンカレント・コレクタは、負荷が高い作業をアプリケーションと同時に実行します。

- G1ガベージ・コレクタ: このサーバー型のコレクタは、大規模なメモリーを保持するマルチプロセッサ・マシンを対象としています。ガベージ・コレクション一時停止時間目標を高い確率で満たしながら、高いスループットを実現します。
G1は、特定のハードウェアおよびオペレーティング・システム構成でデフォルト選択されていることもあれば、-XX:+UseG1GCを使用して明示的に有効にすることもできます。

- CMSコレクタ: このコレクタは、ガベージ・コレクションによる一時停止の短縮が優先され、ガベージ・コレクションとプロセッサ・リソースを共有する余裕があるアプリケーションを対象としています。
CMSコレクタを有効にするには、オプション-XX:+UseConcMarkSweepGCを使用します

CMSコレクタは、JDK 9以降非推奨になりました。

コレクタの選択

それほど厳しい一時停止時間の要件がアプリケーションになければ、まずアプリケーションを実行して、VMにコレクタを選択させます。

必要な場合は、ヒープ・サイズを調整してパフォーマンスを改善します。パフォーマンスがまだ目標を満たさない場合は、次のガイドラインをコレクタ選択の基準として使用してください。

- アプリケーションが小規模のデータ・セット(最大約100MB)を保持する場合、オプション-XX:+UseSerialGCを指定してシリアル・コレクタを選択します。

- アプリケーションをシングル・プロセッサ上で実行し一時停止時間の要件がない場合は、オプション-XX:+UseSerialGCを指定してシリアル・コレクタを選択します。

- (a) ピーク時のアプリケーションのパフォーマンスを最優先し、(b) 一時停止時間の要件がないか、1秒以上の停止時間が許容される場合は、VMにコレクタを選択させるか、-XX:+UseParallelGCを指定してパラレル・コレクタを選択します。

- レスポンス時間を全体のスループットよりも重視し、ガベージ・コレクションの一時停止を約1秒未満に短く保つ必要がある場合は、-XX:+UseG1GCまたは-XX:+UseConcMarkSweepGCを指定してコンカレント・コレクタを選択します。

ヒープ・サイズ、アプリケーションが保持するライブ・データの容量、および使用可能なプロセッサの数と速度にパフォーマンスは依存するため、これらのガイドラインはコレクタを選択するための基準を示しているにすぎません。一時停止時間は特にこれらの要因の影響を受けるため、前に説明した1秒のしきい値は概算値にすぎません。パラレル・コレクタでは、ヒープ・サイズとハードウェアの多くの組合せで一時停止時間が1秒を超えることがあります。逆に、コンカレント・コレクタでは、一部の組合せにおいて、一時停止を1秒未満に保てない場合があります。

推奨されるコレクタで必要なパフォーマンスを達成できない場合は、まずヒープ・サイズと世代サイズを調整して、必要な目標を満たすようにしてください。それでもパフォーマンスが不十分な場合は、別のコレクタを試してみます。一時停止時間を短縮するにはコンカレント・コレクタを、マルチプロセッサ・ハードウェア上で全体のスループットを上げるにはパラレル・コレクタを使用します。

6 パラレル・コレクタ

パラレル・コレクタ(ここではスループット・コレクタとも呼ばれる)は、シリアル・コレクタと同様に世代別コレクタです。シリアル・コレクタとパラレル・コレクタとの主な違いは、パラレル・コレクタには複数のスレッドがあり、これを使用してガベージ・コレクションを高速化する点です。

パラレル・コレクタを有効にするには、コマンド行オプション-XX:+UseParallelGCを使用します。デフォルトで、このオプションを使用すると、マイナー・コレクションもメジャー・コレクションも並列実行して、ガベージ・コレクションのオーバーヘッドをさらに削減します。

トピック

- パラレル・コレクタのガベージ・コレクタのスレッド数

- パラレル・コレクタでの世代の配置

- パラレル・コレクタ・エルゴノミクス

- パラレル・コレクタの動作を指定するオプション

- パラレル・コレクタの目標の優先度

- パラレル・コレクタの世代サイズの調整

- パラレル・コレクタのデフォルト・ヒープ・サイズ

- パラレル・コレクタのヒープ・サイズの初期値と最大値の指定

- 過剰なパラレル・コレクタ時間とOutOfMemoryError

- パラレル・コレクタの測定

パラレル・コレクタのガベージ・コレクタのスレッド数

パラレル・コレクタでは、<N>個( <N>は9以上)のハードウェア・スレッドを使用するマシン上で、 <N>の固定比率をガベージ・コレクタのスレッド数として使用します。

<N>の値が大きい場合、この比率は約5/8です。 <N>の値が8未満の場合、使用される数値は<N>です。特定のプラットフォームでは、比率は5/16に低下します。指定のガベージ・コレクタ・スレッド数はコマンド行オプション(後述)を使用して調整できます。プロセッサが1個のホストでは、並列実行にオーバーヘッド(同期化など)が必要になるため、パラレル・コレクタはシリアル・コレクタよりもパフォーマンスが低くなる可能性があります。ただし、中規模から大規模なヒープを使用してアプリケーションを実行する場合は、2個のプロセッサを搭載したコンピュータではシリアル・コレクタよりもパフォーマンスが若干向上し、プロセッサが3個以上利用可能場合はシリアル・コレクタよりも大幅にパフォーマンスが向上するのが一般的です。

ガベージ・コレクタのスレッド数は、コマンド行オプション-XX:ParallelGCThreads=<N>で制御できます。コマンド行オプションを使用してヒープの調整を行う場合、パラレル・コレクタで高いパフォーマンスを実現するために必要なヒープ・サイズは、シリアル・コレクタで必要なヒープ・サイズと同じです。ただし、パラレル・コレクタは、コレクションによる一時停止を短縮する目的でのみ有効にしてください。マイナー・コレクションでは複数のガベージ・コレクタ・スレッドが使用されているため、コレクション時の若い世代から古い世代への昇格に伴い断片化が発生する可能性があるからです。マイナー・コレクションで使用されている各ガベージ・コレクション・スレッドは昇格のために古い世代の一部を確保し、その使用可能な領域が「昇格バッファ」に分割されるために、断片化の影響を受ける可能性があります。ガベージ・コレクタ・スレッドの数を減らし、古い世代のサイズを増やすことによって、この断片化の影響は低減します。

パラレル・コレクタでの世代の配置

パラレル・コレクタでは世代の配置が異なります。

このような配置を図6-1に示します。

図6-1 パラレル・コレクタでの世代の配置

パラレル・コレクタ・エルゴノミクス

-XX:+UseParallelGCを使用してパラレル・コレクタを選択する場合、自動調整の方法を有効にしているので、ユーザーは世代サイズや他の低レベルのチューニング詳細ではなく、動作を指定できます。

パラレル・コレクタの動作を指定するオプション

ガベージ・コレクションの最大一時停止時間、スループットおよびフットプリント(ヒープ・サイズ)を指定できます。

- ガベージ・コレクションの最大一時停止時間: 最大一時停止時間目標は、コマンド行オプション-XX:MaxGCPauseMillis=<N>で指定します。これは、<N>ミリ秒以下の一時停止時間が望ましいというヒントとして解釈されます。デフォルトでは、最大一時停止時間目標はありません。一時停止時間目標が指定されている場合、ガベージ・コレクションによる一時停止を指定された値以内に維持するよう、ヒープ・サイズとその他のガベージ・コレクション関連パラメータが調整されます。ただし、必要な一時停止時間目標が常に満たされるとはかぎりません。このような調整により、ガベージ・コレクタではアプリケーションの全体的なスループットが低下する可能性があります。

- スループット: スループット目標は、ガベージ・コレクションの実行に消費された時間とガベージ・コレクション以外で消費された時間(アプリケーション時間と呼ばれる)の観点から測定されます。この目標はコマンド行オプション-XX:GCTimeRatio=<N>で指定され、ガベージ・コレクション時間のアプリケーション時間に対する比率を1 / (1 + <N>)に設定します。
たとえば、-XX:GCTimeRatio=19は、ガベージ・コレクションに合計時間の20分の1 (5%)という目標を設定します。デフォルト値は99で、ガベージ・コレクションに1%という時間の目標を設定します。

- フットプリント: ヒープの最大フットプリントはオプション-Xmx<N>を使用して指定します。また、コレクタには、他の目標が満たされている場合はヒープ・サイズを最小化するという暗黙の目標があります。

パラレル・コレクタの目標の優先度

目標は最大一時停止時間目標、スループット目標、最小フットプリント目標で、この順に対処されます。

最大一時停止時間目標を最初に満たします。これを満たした上で、スループット目標に対処します。同様に、先の2つの目標を満たした上で、フットプリント目標を検討します。

パラレル・コレクタの世代サイズの調整

コレクタが保持する平均一時停止時間などの統計は、各コレクションの終了時に更新されます。

その後で、目標を満たしているか確認するためのテストと、必要に応じて世代サイズの調整が行われます。例外として、明示的なガベージ・コレクション(System.gc()の呼出し)は、世代サイズの統計保持や調整上、無視されます。

世代サイズの拡大と縮小は、適切なサイズになるまで段階的に増減されるように、世代サイズの一定割合を単位として徐々に調整されます。拡大と縮小はそれぞれ別の比率で行われます。デフォルトで、世代の拡大率は20%、縮小率は5%です。拡大率はコマンド行オプション-XX:YoungGenerationSizeIncrement=<Y> (若い世代の場合)および-XX:TenuredGenerationSizeIncrement=<T> (古い世代の場合)で制御します。世代の縮小率はコマンド行フラグ-XX:AdaptiveSizeDecrementScaleFactor=<D>で調整します。拡大率がX%の場合、縮小率はX/D%になります。

コレクタの起動時に世代の拡大が決定されると、増加率が割り増しされます。この割増しはコレクションの回数に伴って減衰し、長期的な影響はありません。割増しの目的は、起動時のパフォーマンスを向上させることです。縮小率に割増しはありません。

最大一時停止時間目標が満たされていない場合、一度に縮小できるのは1つの世代のサイズのみです。2つの世代の一時停止時間が目標を超えている場合、一時停止時間が大きい方の世代のサイズが先に縮小されます。

スループット目標が満たされていない場合は、両方の世代サイズが増加されます。どちらも、ガベージ・コレクション合計時間に占めるそれぞれの割合に比例して増加されます。たとえば、若い世代のガベージ・コレクション時間が合計コレクション時間の25%であり、若い世代の完全な拡大率が20%単位である場合、若い世代は5%単位で増加することになります。

パラレル・コレクタのデフォルト・ヒープ・サイズ

コマンド行で初期ヒープ・サイズと最大ヒープ・サイズが指定されていない場合、これらのサイズはマシン上のメモリー容量に基づいて計算されます。初期ヒープ・サイズは物理メモリーの1/64ですが、デフォルトの最大ヒープ・サイズは物理メモリーの1/4です。若い世代に割り当てられる最大領域サイズは、全ヒープ・サイズの1/3です。

パラレル・コレクタのヒープ・サイズの初期値と最大値の指定

オプション-Xms (初期ヒープ・サイズ)および-Xmx (最大ヒープ・サイズ)を使用して、初期および最大のヒープ・サイズを指定できます。

アプリケーションがうまく動作するために必要なヒープ領域がわかっている場合は、-Xmsと-Xmxを同じ値に設定できます。そうでない場合は、JVMが初期ヒープ・サイズを使用して開始され、ヒープ使用量とパフォーマンスのバランスが取れるまで、Javaヒープが増加します。

これらのデフォルト値は、他のパラメータおよびオプションの影響を受ける場合があります。デフォルト値を確認するには、-XX:+PrintFlagsFinalオプションを使用し、出力から-XX:MaxHeapSizeを探します。たとえば、LinuxまたはSolarisでは、次を実行できます。

java -XX:+PrintFlagsFinal <GC options> -version | grep MaxHeapSize

過剰なパラレル・コレクタ時間とOutOfMemoryError

ガベージ・コレクション(GC)で時間がかかりすぎると、パラレル・コレクタはOutOfMemoryErrorをスローします。

ガベージ・コレクションに合計時間の98%より多く費やされ、ヒープのリカバリが2%未満である場合に、OutOfMemoryErrorがスローされます。この機能は、ヒープが小さすぎるためにアプリケーションが長時間わたって処理が進まないまま実行中の状態に陥ることを回避する目的で設計されています。必要な場合は、コマンド行に-XX:-UseGCOverheadLimitオプションを追加することで、この機能を無効にできます。

パラレル・コレクタの測定

パラレル・コレクタからの冗長ガベージ・コレクタ出力は、シリアル・コレクタからのものと基本的には同じです。

7 モーストリ・コンカレント・コレクタ

モーストリ・コンカレント・コレクタは、一部の作業をアプリケーションと同時に実行するため、このように呼ばれています。Java HotSpot VMには、2つのモーストリ・コンカレント・コレクタが含まれています。

- コンカレント・マーク・スイープ(CMS)コレクタ: このコレクタは、ガベージ・コレクションによる一時停止の短縮が優先され、ガベージ・コレクションとプロセッサ・リソースを共有する余裕があるアプリケーションを対象としています。

- ガベージファースト(G1)ガベージ・コレクタ: このサーバー型のコレクタは、大規模なメモリーを保持するマルチプロセッサ・マシンを対象としています。ガベージ・コレクション一時停止時間目標を高い確率で満たしながら、高いスループットを実現します。

モーストリ・コンカレント・コレクタのオーバーヘッド

モーストリ・コンカレント・コレクタは、(本来ならばアプリケーションで使用できるはずの)プロセッサ・リソースとメジャー・コレクションの一時停止時間の短縮をトレードオフします。

わかりやすいオーバーヘッドとしては、コレクションの並行処理部分で1つ以上のプロセッサが使用される点があげられます。N個のプロセッサを搭載したシステムでは、コレクションの並行処理部分で、使用可能なプロセッサのK/N (1 <= K <= ceiling{N/4})を使用します。並行処理を有効にすると、コンカレント・フェーズ中のプロセッサの使用以外にもオーバーヘッドが発生します。したがって、コンカレント・コレクタでは通常、ガベージ・コレクションによる一時停止が大幅に短くなる一方で、アプリケーションのスループットは他のコレクタと比べると若干低下する傾向があります。

複数の処理コアを搭載したマシンでは、コレクションの並行処理中にアプリケーション・スレッドがプロセッサを使用できるので、コンカレント・ガベージ・コレクタ・スレッドによってアプリケーションが一時停止されることはありません。これにより通常は一時停止が短くなりますが、この場合もアプリケーションで使用できるプロセッサ・リソースが少なくなるので、特にアプリケーションがすべての処理コアを最大限に使用する場合は処理速度の低下が予想されます。Nが増えると、コンカレント・ガベージ・コレクションに伴うプロセッサ・リソースの減少が小さくなり、コンカレント・コレクションのメリットが増大します。このような拡張の可能な制限の詳細は、「並行モードの失敗」を参照してください。

コンカレント・フェーズ中はガベージ・コレクションで1つ以上のプロセッサが使用されるため、一般に単一プロセッサ(シングル・コア)マシンではコンカレント・コレクタによるメリットはありません。

8 コンカレント・マーク・スイープ(CMS)コレクタ

コンカレント・マーク・スイープ(CMS)コレクタは、ガベージ・コレクションによる一時停止の短縮が優先され、アプリケーションの実行中にガベージ・コレクタとプロセッサ・リソースを共有する余裕があるアプリケーション向けに設計されています。

一般に、データが比較的大量で寿命が長く(古い世代が大きい)、プロセッサを2個以上搭載したマシンで実行されるアプリケーションは、このコレクタを使用することによってメリットを得られるという傾向があります。CMSコレクタを有効にするには、コマンド行オプション-XX:+UseConcMarkSweepGCを使用します。

CMSコレクタは、非推奨になりました。かわりにガベージファースト・コレクタの使用を検討してください。

トピック

- コンカレント・マーク・スイープ・コレクタのパフォーマンスと構造

- 並行モードの失敗

- 過剰なGC時間とOutOfMemoryError

- コンカレント・マーク・スイープ・コレクタとフローティング・ガベージ

- コンカレント・マーク・スイープ・コレクタの一時停止

- コンカレント・マーク・スイープ・コレクタのコンカレント・フェーズ

- コンカレント・コレクション・サイクルの開始

- 一時停止のスケジューリング

- コンカレント・マーク・スイープ・コレクタの測定

コンカレント・マーク・スイープ・コレクタのパフォーマンスと構造

他の使用可能なコレクタと同様に、CMSコレクタは世代別です。つまり、マイナー・コレクションとメジャー・コレクションの両方が発生します。CMSコレクタは、別々のガベージ・コレクタ・スレッドを使用することでメジャー・コレクションによる一時停止時間を短縮し、アプリケーション・スレッドの実行と並行して到達可能なオブジェクトをトレースします。

各メジャー・コレクション・サイクルにおいて、CMSコレクタはコレクションの開始時と半ば近くに、すべてのアプリケーション・スレッドを短期間停止します。2番目の一時停止は、この2回の一時停止のうちで長くなる傾向があります。どちらの一時停止でも、マルチスレッドでコレクション作業が行われます。残りのコレクション作業(ライブ・オブジェクトのトレースと到達不可能なオブジェクトのスイープの大部分を含む)は1つ以上のガベージ・コレクタ・スレッドで実行されます。マイナー・コレクションは実行中のメジャー・サイクルとのインターリーブが可能で、パラレル・コレクタと同様の方法で実行されます(具体的には、マイナー・コレクション中にアプリケーション・スレッドが停止されます)。

並行モードの失敗

CMSコレクタは、アプリケーション・スレッドと同時実行の1つ以上のガベージ・コレクタ・スレッドを使用して、古い世代がいっぱいになる前に、この世代のコレクションを完了しようとします。

前に説明したように、CMSコレクタの通常の操作では、トレース作業とスイープ作業のほとんどをアプリケーション・スレッドの実行中に行うため、アプリケーション・スレッドの一時停止は非常に短くなります。ただし、古い世代がいっぱいになる前に到達不可能なオブジェクトの回収をCMSコレクタで完了できなかったり、古い世代内の使用可能な空き領域ブロックで割当てを満たすことができない場合は、アプリケーションを一時停止して、すべてのアプリケーション・スレッドが停止した状態でコレクションを完了させることになります。コレクションを並行して完了できないことを並行モードの失敗と呼び、CMSコレクタのパラメータを調整する必要があることを示唆します。明示的なガベージ・コレクション(System.gc())によって、またはガベージ・コレクションが診断ツールに情報を提供する必要がある場合に、コンカレント・コレクションが中断されると、並行モードの中断が報告されます。

過剰なGC時間とOutOfMemoryError

ガベージ・コレクションに時間がかかりすぎると、CMSコレクタはOutOfMemoryErrorをスローします。具体的には、ガベージ・コレクションに合計時間の98%より多く費やされ、ヒープのリカバリが2%未満である場合に、OutOfMemoryErrorがスローされます。

この機能は、ヒープが小さすぎるためにアプリケーションが長時間わたって処理が進まないまま実行中の状態に陥ることを回避する目的で設計されています。必要な場合は、コマンド行に-XX:-UseGCOverheadLimitオプションを追加することで、この機能を無効にできます。

このポリシーはパラレル・コレクタと同じですが、コンカレント・コレクションの実行に費やされた時間は98%の時間制限に加算されないという点が異なります。つまり、過剰なGC時間として考慮されるのは、アプリケーションの停止中に実行されたコレクションのみです。このようなコレクションは、並行モードの失敗または明示的コレクションのリクエスト(System.gc()の呼出しなど)に伴うのが一般的です。

コンカレント・マーク・スイープ・コレクタとフローティング・ガベージ

CMSコレクタは、Java HotSpot VMに含まれる他のすべてのコレクタと同様にトレース・コレクタであり、少なくともヒープ内で到達可能なすべてのオブジェクトを識別します。

Richard JonesおよびRafael D.Lins氏の著書『Garbage Collection: Algorithms for Automated Dynamic Memory』によると、これはインクリメンタル更新コレクタです。アプリケーション・スレッドとガベージ・コレクタ・スレッドはメジャー・コレクション中に並行して実行されるため、ガベージ・コレクタ・スレッドによってトレースされたオブジェクトが、後でコレクション・プロセスが終了するまでに、到達不可能になる場合があります。このように到達不可能で、まだ回収されていないオブジェクトは、ローティング・ガベージと呼ばれます。フローティング・ガベージの総量は、コンカレント・コレクション・サイクルの期間とアプリケーションによる参照更新の頻度(ミューテーションとも呼ばれる)に左右されます。さらに、若い世代と古い世代は別々に収集されるので、相互に他方のルート・ソースとして機能します。大まかな目安として、フローティング・ガベージに備え、古い世代のサイズを20%拡大してみてください。あるコンカレント・コレクション・サイクルの終了時にヒープ内にあったフローティング・ガベージは、次のコレクション・サイクル時に収集されます。

コンカレント・マーク・スイープ・コレクタの一時停止

CMSコレクタは、コンカレント・コレクション・サイクル時にアプリケーションを2回一時停止します。最初の一時停止は、ルートから直接到達可能なオブジェクト(アプリケーション・スレッドのスタックやレジスタからのオブジェクト参照、静的オブジェクトなど)と、ヒープ内のどこか(若い世代など)から到達可能なオブジェクトに、ライブのマークを付けるために行われます。

最初の一時停止は、初期マークの一時停止と呼ばれます。2番目の一時停止はコンカレント・トレース・フェーズの最後に発生し、CMSコレクタがオブジェクトのトレースを終了した後にアプリケーション・スレッドがそのオブジェクト内の参照を更新したことが原因でコンカレント・トレース・フェーズ中に見つけることができなかったオブジェクトを検出します。この2番目の一時停止は、再マークの一時停止と呼ばれます。

コンカレント・マーク・スイープ・コレクタのコンカレント・フェーズ

初期マークの一時停止と再マークの一時停止の間に、到達可能なオブジェクト・グラフのコンカレント・トレースが発生します。

このコンカレント・トレース・フェーズ中は、本来ならばアプリケーションに使用できたはずのプロセッサ・リソースを、1つ以上のコンカレント・ガベージ・コレクタ・スレッドが使用している場合があります。その結果、CPUバウンドなアプリケーションは、このようなコンカレント・フェーズ中に、アプリケーション・スレッドが一時停止されていない場合でも、アプリケーションのスループットが相応に低下する場合があります。再マークの一時停止後のコンカレント・スイープ・フェーズでは、到達不可能と識別されたオブジェクトを収集します。CMSコレクタは、コレクション・サイクルが完了すると、次のメジャー・コレクション・サイクルが開始するまで待機しますが、その間は計算のリソースをほとんど消費しません。

コンカレント・コレクション・サイクルの開始

シリアル・コレクタでは、古い世代がいっぱいになるたびにメジャー・コレクションが発生し、コレクションの実行中はすべてのアプリケーション・スレッドが停止します。これに対し、CMSコレクタのコンカレント・コレクションでは、古い世代がいっぱいになる前にコレクションを完了できるよう、開始のタイミングを計る必要があります。そうしないと、並行モードの失敗に伴いアプリケーションの一時停止が長くなるおそれがあります。コンカレント・コレクションを開始するには、複数の方法があります。

CMSコレクタでは、最新の履歴に基づいて、古い世代が枯渇するまでの残り時間とコンカレント・コレクション・サイクルに必要な時間を予測しています。これらの動的な予測を使用して、古い世代が枯渇する前にコレクション・サイクルが完了するよう、コンカレント・コレクション・サイクルが開始されます。並行モードの失敗はコストが非常に高くなる可能性があるので、このような予測は安全のための措置です。

古い世代の占有率が開始占有率(古い世代の割合)を超えた場合にも、コンカレント・コレクションが開始されます。この開始占有率のデフォルトのしきい値は約92%ですが、この値はリリースごとに変更される場合があります。この値は、コマンド行オプション-XX:CMSInitiatingOccupancyFraction=<N> (<N>は、古い世代のサイズの割合を0から100の整数で表した値)を使用して、手動で調整できます。

一時停止のスケジューリング

若い世代のコレクションと古い世代のコレクションの一時停止は別々に行われます。

両方が重なることはありませんが、間断なく発生する場合があり、あるコレクションによる一時停止の直後に別のコレクションによる停止が続くと、それが1つの長い一時停止に見えることがあります。これを回避するため、CMSコレクタでは前回と次回の若い世代の一時停止のほぼ中間に、再マークの一時停止をスケジュールしようとします。初期マークの一時停止(再マークの一時停止よりも通常は大幅に短い)には、このスケジューリングは現在行われていません。

コンカレント・マーク・スイープ・コレクタの測定

次に、オプション-Xlog:gcを指定したCMSコレクタの出力を示します。

[121,834s][info][gc] GC(657) Pause Initial Mark 191M->191M(485M) (121,831s, 121,834s) 3,433ms
[121,835s][info][gc] GC(657) Concurrent Mark (121,835s)
[121,889s][info][gc] GC(657) Concurrent Mark (121,835s, 121,889s) 54,330ms
[121,889s][info][gc] GC(657) Concurrent Preclean (121,889s)
[121,892s][info][gc] GC(657) Concurrent Preclean (121,889s, 121,892s) 2,781ms
[121,892s][info][gc] GC(657) Concurrent Abortable Preclean (121,892s)
[121,949s][info][gc] GC(658) Pause Young (Allocation Failure) 324M->199M(485M) (121,929s, 121,949s) 19,705ms
[122,068s][info][gc] GC(659) Pause Young (Allocation Failure) 333M->200M(485M) (122,043s, 122,068s) 24,892ms
[122,075s][info][gc] GC(657) Concurrent Abortable Preclean (121,892s, 122,075s) 182,989ms
[122,087s][info][gc] GC(657) Pause Remark 209M->209M(485M) (122,076s, 122,087s) 11,373ms
[122,087s][info][gc] GC(657) Concurrent Sweep (122,087s)
[122,193s][info][gc] GC(660) Pause Young (Allocation Failure) 301M->165M(485M) (122,181s, 122,193s) 12,151ms
[122,254s][info][gc] GC(657) Concurrent Sweep (122,087s, 122,254s) 166,758ms
[122,254s][info][gc] GC(657) Concurrent Reset (122,254s)
[122,255s][info][gc] GC(657) Concurrent Reset (122,254s, 122,255s) 0,952ms
[122,297s][info][gc] GC(661) Pause Young (Allocation Failure) 259M->128M(485M) (122,291s, 122,297s) 5,797ms

注意:
CMSコレクション(GC ID: 657)の出力中にマイナー・コレクション (GC ID: 658、659、660)からの出力が点在していることに注意してください。通常、コンカレント・コレクション・サイクル中にマイナー・コレクションが何回も発生します。一時停止の初期マークは、コンカレント・コレクション・サイクルの開始を示します。「Concurrent」で始まる行は、コンカレント・フェーズの開始と終了を示します。一時停止の再マークは最後の一時停止です。プレクリーニングフェーズは前述の例にありません。プレクリーニングは、再マーク・フェーズの準備として並行実行できる作業を表します。最終フェーズは「Concurrent Reset」で示され、次回のコンカレント・コレクションの準備として行われます。

通常、初期マークの一時停止はマイナー・コレクションの一時停止時間よりも短くなります。コンカレント・フェーズ(コンカレント・マーク、コンカレント・プレクリーニングおよびコンカレント・スイープ)は、マイナー・コレクションの一時停止よりも大幅に長くなるのが一般的です(CMSコレクタの出力例を参照)。ただし、このようなコンカレント・フェーズ中にアプリケーションが一時停止されることはありません。通常、再マークの一時停止はマイナー・コレクションと同程度の長さです。再マークの一時停止が影響を受けるのは、特定のアプリケーション特性(たとえば、オブジェクト変更の頻度が高いと、この一時停止が長くなる可能性があります)と、前回のマイナー・コレクションからの経過時間(たとえば、若い世代のオブジェクトが増えると、この一時停止が長くなる可能性があります)によります。

9 ガベージファースト・ガベージ・コレクタ

この項では、ガベージファースト(G1)ガベージ・コレクタ(GC)について説明します。

トピック

- ガベージファースト・ガベージ・コレクタの概要

- G1の有効化

- 基本概念

- ヒープ・レイアウト

- ガベージ・コレクション・サイクル

- ガベージファーストの内部

- 開始ヒープ占有率の決定

- マーキング

- 非常にタイトなヒープの状況における動作

- 開始ヒープ占有率の決定

- 大型オブジェクト

- 若い世代のみのフェーズの世代のサイズ設定

- 領域回収フェーズの世代のサイズ設定

- G1 GCのエルゴノミック・デフォルト

- 他のコレクタとの比較

ガベージファースト・ガベージ・コレクタの概要

ガベージファースト(G1)ガベージ・コレクタは、大規模なメモリーを保持するマルチプロセッサ・マシンを対象としています。これはガベージ・コレクション一時停止時間目標を高い確率で満たそうとする一方、構成の必要がなく、高いスループットを実現します。G1はレイテンシとスループットの間で最適なバランスを取ることを目標とし、現在のターゲット・アプリケーションと次の機能が含まれる環境を使用します。

- 最大10GBまたはそれ以上のヒープ・サイズ(Javaヒープの50%超がライブ・データで占められている)。

- 時間が経つと大きく変化する可能性のあるオブジェクトの割当て率および昇格率。

- ヒープ内の大量の断片化。

- 数百ミリ秒以内の予測可能な一時停止ターゲット目標(長時間のガベージ・コレクションの一時停止を回避)。

G1はコンカレント・マーク・スイープ(CMS)コレクタのかわりとなるものです。これはデフォルトのコレクタでもあります。

G1コレクタは高いパフォーマンスを実現し、次の項で説明されているいくつかの方法で一時停止時間目標を満たそうとします。

G1の有効化

ガベージファースト・ガベージ・コレクタはデフォルト・コレクタであるため、通常、追加の処理を実行する必要はありません。コマンド行で-XX:+UseG1GCを指定すると、これを明示的に有効化できます。

基本概念

G1は、世代別、増分的、並列型、モーストリ・コンカレント、stop-the-world型で退避型のガベージ・コレクタであり、stop-the-world型の一時停止ごとに一時停止時間目標を監視します。他のコレクタと同様に、G1では(仮想の)若い世代と古い世代にヒープを分割します。領域の回収は若い世代に行う方が効果的であるため、若い世代に対して集中的に行われますが、古い世代に対して行われることもあります

一部の操作は常にstop-the-world型の一時停止で実行され、スループットを向上させます。グローバル・マーキングのようなヒープ全体の操作など、アプリケーションを停止すると時間がかかる他の操作は、アプリケーションと同時に並列実行されます。領域の回収にstop-the-world型の一時停止を短くするために、G1は領域回収を徐々に増分しながら並列実行します。G1では、前回のアプリケーションの動作とガベージ・コレクションの一時停止に関する情報をトラッキングして予測し、関連するコストのモデルを作成します。この情報を使用して、一時停止で実行される作業のサイズを判定します。たとえば、G1では、最も効率的な場所の領域を最初に回収します(ガベージでほぼいっぱいになっている領域を最初に行うため、このように呼ばれています)。

G1では、主に退避を使用して領域を回収します。選択したメモリー領域内で見つかったライブ・オブジェクトは新しいメモリー領域にコピーされ、プロセスでこれらを圧縮します。退避が完了すると、ライブ・オブジェクトで占有されていた領域はアプリケーションによる割当てに再使用されます。

ガベージファースト・コレクタは、リアルタイム・コレクタではありません。時間をかけて設定された一時停止時間目標を高い確率で満たそうとしますが、特定の一時停止では必ずしも絶対確実ではありません。

ヒープ・レイアウト

G1ではヒープを均等サイズのヒープ・リージョン・セットに分割し、図9-1に示すように、それぞれは連続する一連の仮想メモリーです。リージョンとは、メモリー割当ておよびメモリー回収の単位です。常に、これらの各リージョンは空であるか(明るいグレー)、特定の世代(若いまたは古い世代)に割り当てることができます。メモリーに対するリクエストが発生すると、メモリー・マネージャが空きのリージョンを割り当てます。メモリー・マネージャはこれらをある世代に割り当て、次に空き領域としてアプリケーションにこれらを返却し、そこに自分自身を割り当てることができます。

図9-1 G1ガベージ・コレクタのヒープ・レイアウト

若い世代には、Edenリージョン(赤)とSurvivorリージョン(Sが付いた赤)が含まれています。これらのリージョンは、他のコレクタの連続的な各領域と同じ機能を備えており、G1において通常、これらのリージョンはメモリー内で連続的でないパターンで配置されている点が異なります。古いリージョン(水色)は古い世代を構成しています。古い世代のリージョンは複数のリージョンにまたがるオブジェクトに対してサイズが大きくなることがあります(Hが付いた水色)。

アプリケーションは、古い世代に属しているために直接割り当てられている大型オブジェクトを除いて、常に若い世代(Edenリージョン)に割り当てられます。

G1ガベージ・コレクションの一時停止では、全体として若い世代の領域を回収し、任意のコレクションの一時停止で古い世代のリージョンの領域を追加で回収できます。一時停止中に、G1はオブジェクトをこのコレクション・セットからヒープ内の1つ以上の異なるリージョンにコピーします。オブジェクトの移動先リージョンはそのオブジェクトの移動元リージョンによって異なります。若い世代全体がSurvivorまたは古いリージョンにコピーされ、古いリージョンのオブジェクトが、エージングを使用して他の異なる古いリージョンにコピーされます。

ガベージ・コレクション・サイクル

高いレベルで、G1コレクタは2つのフェーズを交代させます。若い世代のみのフェーズには、現在使用可能なメモリーを古い世代のオブジェクトで徐々に満たすガベージ・コレクションが含まれています。領域回収フェーズでは、G1は増分しながら古い世代の領域を回収し、さらに若い世代に対応します。その後、このサイクルでは若い世代のみのフェーズを再度開始します。

図9-2に、このサイクルの概要および発生する可能性のあるガベージ・コレクションの一時停止の順序の例を示します。

図9-2 ガベージ・コレクションのサイクルの概要

次のリストに、フェーズ、一時停止、G1ガベージ・コレクション・サイクルのフェーズ間での推移を詳細に示します。

1. 若い世代のみのフェーズ: このフェーズは、オブジェクトを古い世代に昇格させる、いくつかの若い世代のみのコレクションから開始します。若い世代のみのフェーズと領域回収フェーズ間の推移は、古い世代の占有率が特定のしきい値(開始ヒープ占有率しきい値)に達したときにのみ、開始します。この時点で、G1は通常の若い世代のみのコレクションのかわりに、初期マークの若い世代のみのコレクションをスケジュールします。

- 初期マーク: このタイプのコレクションはマーキング・プロセスを開始し、通常の若い世代のみのコレクションも実行します。コンカレント・マーキングでは、次の領域回収フェーズで維持される、古い世代のリージョンの現在到達可能なすべての(ライブ)オブジェクトを判定します。マーキングが完全に終了していない場合、通常の若い世代のみのコレクションが発生することがあります。マーキングは、再マークとクリーン・アップの2つの固有のstop-the-world型の一時停止で終了します。

- 再マーク: この一時停止は、マーキング自体をファイナライズし、グローバル参照プロセスとクラスのアップロードを実行します。再マークとクリーンアップの間に、G1はライブ情報のサマリーを同時に計算します。これがファイナライズされ、クリーン・アップの一時停止で使用されて、内部データ構造を更新します。

- クリーン・アップ: この一時停止も完全に空のリージョンを回収し、領域回収フェーズが実際に後に続くかどうかを判定します。領域回収フェーズが後に続いた場合、若い世代のみの一時停止は、単一の若い世代のみのコレクションで完了します。

2. 領域回収フェーズ: このフェーズは複数の混合コレクションから構成され、若い世代のリージョンに加えて、古い世代のリージョン・セットのライブ・オブジェクトも退避します。領域回収フェーズは、古い世代のリージョンをこれ以上退避しても、十分な空き領域を作り出せないとG1が判断した場合に終了します。

領域回収後、コレクション・サイクルが別の若い世代のみのフェーズから再度開始します。バックアップとして、アプリケーションがライブ情報の収集中にメモリーを使い果たした場合、G1では他のコレクタのようなstop-the-world型のインプレース・フル・ヒープ圧縮(フルGC)を実行します。

ガベージファーストの内部

この項では、ガベージファースト(G1)ガベージ・コレクタの重要な詳細情報について説明します。

開始ヒープ占有率の決定

開始ヒープ占有率(IHOP)は、初期マーク・コレクションがトリガーされるしきい値で、古い世代のサイズの割合として定義されます。

G1では、デフォルトで、マーキングにかかった時間とマーキング・サイクル時に古い世代に通常割り当てられるメモリーの量を監視することで、最適なIHOPを自動的に判定します。この機能は、適応型IHOPと呼ばれます。この機能がアクティブな場合、オプション-XX:InitiatingHeapOccupancyPercentは、開始ヒープ占有率しきい値を予測するのに十分な監視結果がなければ、現在の古い世代のサイズの割合として初期値を判定します。オプション-XX:-G1UseAdaptiveIHOPを使用して、G1のこの動作をオフにします。この場合、-XX:InitiatingHeapOccupancyPercentの値は常にこのしきい値を判定します。

内部的に、適応型IHOPは開始ヒープ占有率を設定しようとします。これにより、古い世代の占有率が現在の古い世代の最大サイズから余分なバッファとして-XX:G1HeapReservePercentの値を差し引いた値に達したときに、領域回収フェーズの最初の混合ガベージ・コレクションが開始します。

マーキング

G1マーキングでは、Snapshot-At-The-Beginning (SATB)と呼ばれるアルゴリズムを使用します。マーキングの開始時にライブだったすべてのオブジェクトがマーキングの残りに対してライブとみなされている場合、初期マークの一時停止時にヒープの仮想スナップショットを取得します。これは、マーキング時に寿命を終えた(到達不能な)オブジェクトが領域回収のためにライブとしてみなされているということです(一部例外あり)。他のコレクタと比較すると、これによって追加のメモリーが不適切に保持される場合があります。ただし、SATBでは再マークの一時停止時に適切なレイテンシが発生する可能性があります。このマーキング時にライブ・オブジェクトとみなされたオブジェクトは、次回のマーキング時に回収されます。マーキングでの問題の詳細は、「ガベージファースト・ガベージ・コレクタのチューニング」のトピックを参照してください。

非常にタイトなヒープの状況における動作

退避でコピーする領域を見つけられないほど、アプリケーションが大量のメモリーを保持している場合、退避は失敗します。退避が失敗したということは、G1で、まだ移動していないオブジェクトをコピーせずに、すでに新しい場所に移動したオブジェクトを保持して現在のガベージ・コレクションを完了しようとしており、オブジェクト間の参照のみを調整していることを意味します。退避が失敗すると、追加のオーバーヘッドが発生することがありますが、一般的に他の若いコレクションと速度は変わりません。退避が失敗したガベージ・コレクションの後で、G1はアプリケーションを通常どおりに再開し、他の措置は取りません。G1では、退避の失敗はガベージ・コレクションの終了間際に発生すると想定しています。すなわち、ほとんどのオブジェクトはすでに移動していて、マーキングが完了して領域の回収が開始するまで、アプリケーションの実行を続けるのに十分な領域が残っているということです。

この想定が当てはまらない場合、G1は最終的にフルGCをスケジュールします。このタイプのコレクションは、ヒープ全体のインプレース圧縮を実行します。これは時間がかかることがあります。

割当ての失敗またはメモリーからの通知の前のフルGCの問題の詳細は、「ガベージファースト・ガベージ・コレクタのチューニング」のトピックを参照してください。

大型オブジェクト

大型オブジェクトとは、リージョンの半分のサイズ以上のオブジェクトです。「G1 GCのエルゴノミック・デフォルト」の項で記述されているように、-XX:G1HeapRegionSizeオプションを使用して設定されないかぎり、現在のリージョン・サイズはエルゴノミックに決定されます。

これらの大型オブジェクトは次のように扱われることがあります。

- すべての大型オブジェクトは、古い世代の連続的なリージョンの順序に従って割り当てられます。オブジェクト自体の開始は、常に、最初のリージョンの開始時にその順序で行われます。オブジェクト全体が回収されるまで、順序内の最後のリージョンで残っている領域が割当てのために失われます。

- 一般的に、大型オブジェクトは到達不能になった場合、クリーン・アップの一時停止中またはフルGC中のマーキングの終了時にのみ回収できます。ただし、プリミティブなタイプの配列(例: bool、すべての種類の整数、浮動小数点の値)の大型オブジェクト用に特殊なプロビジョニングがあります。G1では、大型オブジェクトがガベージ・コレクションの一時停止で多数のオブジェクトから参照されなくなった場合、大型オブジェクトを回収しようとします。この動作はデフォルトで有効になっていますが、オプション-XX:G1EagerReclaimHumongousObjectsを指定すると無効化できます。

- 大型オブジェクトの割当てによってガベージ・コレクションの一時停止が早く発生することがあります。G1は、大型オブジェクトの割当てごとに開始ヒープ占有率しきい値をチェックし、現在の占有率がしきい値を超えると、即座に初期マークの若いコレクションを強制できます。

- 大型オブジェクトは、フルGC時でも移動しません。このため、フルGCが早く低速化するか、リージョン領域の断片化のために空き領域を大量に保持したまま予期しないメモリー不足の状態になる可能性があります。

若い世代のみのフェーズの世代のサイズ設定

若い世代のみのフェーズで、収集するリージョンのセット(コレクション・セット)は若い世代のリージョンのみから構成されます。G1は、若い世代のみのコレクションの終了時に若い世代のサイズを決定します。このように、G1は、実際の一時停止時間の長時間に及ぶ監視に基づいて、-XX:MaxGCPauseTimeMillisと-XX:PauseTimeIntervalMillisを使用して設定された一時停止時間目標を満たすことができます。同様のサイズの若い世代が退避するのにどのくらい時間がかかるかを考慮します。これには、コレクション時にコピーする必要があったオブジェクト数やこれらのオブジェクトが相互接続された方法などの情報が含まれます。

制限がなければ、G1は、-XX:G1NewSizePercentと-XX:G1MaxNewSizePercentが一時停止時間を満たすために決定する値の間で適応させながら若い世代のサイズを決定します。長い一時停止を修正する方法の詳細は、「ガベージファースト・ガベージ・コレクタのチューニング」を参照してください。

領域回収フェーズの世代のサイズ設定

領域回収フェーズ時に、G1では、1回のガベージ・コレクションの一時停止で古い世代で回収される領域の量を最大化しようとします。若い世代のサイズは許可される最小限に設定され、通常は、-XX:G1NewSizePercentで決定され、リージョンをさらに追加することにより一時停止時間目標を超えると、G1が判定するまで、領域を回収する古い世代のリージョンが追加されます。特定のガベージ・コレクションの一時停止で、G1は古い世代のリージョンを回収の効率性の高い順に追加します。残りの使用可能な時間に最後のコレクション・セットを取得します。

ガベージ・コレクションごとに取得する古い世代のリージョン数は、収集する候補の古い世代のリージョン数で下限が設定されていて(コレクション・セットの候補リージョン)、 -XX:G1MixedGCCountTargetで決定される領域回収フェーズの長さで分割されます。コレクション・セットの候補リージョンは、フェーズの開始時に-XX:G1MixedGCLiveThresholdPercentより低い占有率のすべての古い世代のリージョンです。

コレクション・セットの候補リージョンで回収可能な領域の残りの量が-XX:G1HeapWastePercentによって設定された割合より低い場合に、フェーズが終了します。

G1が使用する古い世代のリージョンの数および長い混合コレクションの一時停止を回避する方法の詳細は、「ガベージファースト・ガベージ・コレクタのチューニング」を参照してください。

G1 GCのエルゴノミック・デフォルト

このトピックでは、G1に固有の重要なデフォルト設定とそのデフォルト値の概要について説明します。追加のオプションを指定せずにG1を使用して想定される動作およびリソースの使用状況の概要についても説明します。

表9-1 G1 GCのエルゴノミック・デフォルト

オプションとデフォルト値

説明

-XX:MaxGCPauseMillis=200

最大一時停止時間の目標。

-XX:GCPauseTimeInterval=<ergo>

最大一時停止時間間隔の目標。デフォルトではG1は目標を設定せず、極端な場合にガベージ・コレクションを連続的に実行します。

-XX:ParallelGCThreads=<ergo>

ガベージ・コレクションの一時停止時に並行作業に使用するスレッドの最大数。これは、VMが実行されるコンピュータの使用可能なスレッド数から導出されます。たとえば、プロセスに使用可能なCPUスレッド数が8以下の場合、これを使用します。これ以外の場合、最終スレッド数よりも大きいスレッドの8分の5を追加します。

-XX:ConcGCThreads=<ergo>

並行作業に使用されるスレッドの最大数。デフォルトでは、この値は-XX:ParallelGCThreads を4で割った値です。

-XX:+G1UseAdaptiveIHOP

-XX:InitiatingHeapOccupancyPercent=45

開始ヒープ占有率を制御するデフォルトは、その値の適応的な決定がオンになっていて、マーク開始のしきい値として、最初のいくつかのコレクション・サイクルでG1が古い世代の45%の占有率を使用していることを示します。

-XX:G1HeapRegionSize=<ergo>

初期および最大ヒープ・サイズに基づいたヒープ・リージョン・サイズの設定。したがって、そのヒープには2048個のヒープ・リージョンが含まれています。ヒープ・リージョンのサイズは1から32MBに変化する可能性があり、2の累乗である必要があります。

-XX:G1NewSizePercent=5

-XX:G1MaxNewSizePercent=60

若い世代の合計サイズは、使用中の現在のJavaヒープの割合であるため、これらの2つの値で変化します。

-XX:G1HeapWastePercent=5

コレクション・セットの候補内の許容される回収されない領域の割合。コレクション・セットの候補内の空き領域がこれより低い場合、G1は領域回収フェーズを停止します。

-XX:G1MixedGCCountTarget=8

多数のコレクション内で領域回収フェーズの想定される長さ。

-XX:G1MixedGCLiveThresholdPercent=85

この割合より高い占有率のライブ・オブジェクトを含む古い世代のリージョンは、この領域回収フェーズで収集されません。

注意:
<ergo>は、実際の値が環境によってエルゴノミックに決定されるという意味です。

他のコレクタとの比較

これは、G1と他のコレクタとの主な相違点のサマリーです。

- パラレルGCは、全体として古い世代の領域を圧縮および回収できます。G1では、複数のより短いコレクション間でこの作業を分散します。これにより、一時停止時間が短縮されますがスループットが犠牲になる可能性があります。

- CMSと同様に、G1では古い世代の領域回収の一部を同時に実行します。ただし、CMSは古い世代のヒープを最適化できず、最終的に長いフルGCを実行します。

- G1では、他のコレクタよりも高いオーバーヘッドを示し、この同時性のためにスループットに影響を及ぼす場合があります。

動作方法のために、G1はガベージ・コレクションの効率性を向上させる固有のメカニズムを備えています。

- G1では、コレクション時に古い世代の大きな空の領域を完全に回収できます。これは、多くの不要なガベージ・コレクションを回避して、大量の領域を容易に解放できます。

- オプションで、G1は同時にJavaヒープで文字列の重複を除外できます。

古い世代からの大きな空のオブジェクトの回収は、常に有効になっています。オプション-XX:-G1EagerReclaimHumongousObjectsを指定すると、この機能を無効化できます。デフォルトで、文字列の重複除外は無効になっています。オプション -XX:+G1EnableStringDeduplicationを使用すると、これを有効化できます。

10 ガベージファースト・ガベージ・コレクタのチューニング

この項では、ユーザーの要件を満たさない場合にガベージファースト・ガベージ・コレクタ(G1 GC)の動作を適応する方法を説明します。

トピック

- G1の一般的な推奨事項

- 他のコレクタからG1への移行

- G1パフォーマンスの向上

- フル・ガベージ・コレクションの監視

- 大型オブジェクトの断片化

- レイテンシのためのチューニング

- 通常と異なるシステムまたはリアル・タイムの使用状況

- 処理に長時間かかる参照オブジェクト

- 時間がかかりすぎる若い世代のみのコレクション

- 時間がかかりすぎる混合コレクション

- 高いRSの更新およびRSのスキャン時間

- スループットのためのチューニング

- ヒープ・サイズのためのチューニング

- チューニング可能なデフォルト設定

G1の一般的な推奨事項

一般的な推奨事項は、G1をデフォルト設定で使用することです。異なる一時停止時間目標を設定したり、必要に応じて-Xmxを使用して、最大Javaヒープ・サイズを設定することもあります。

G1のデフォルト設定は、他のコレクタと異なってバランスが取られています。デフォルト構成のG1の目標は、最大スループットでもなく、最低のレイテンシでもなく、高いスループットで相対的に小さな統一された一時停止を行うことです。ただし、ヒープおよび一時停止時間の制御において領域を増分的に回収するG1のメカニズムにより、アプリケーション・スレッドにおいても、領域回収の効率性においてもオーバーヘッドが生じます。

高いスループットを優先する場合、-XX:MaxGCPauseMillisを使用して一時停止時間目標を緩くするか、より大きいヒープを提供します。レイテンシが主要な要件である場合、一時停止時間ターゲットを変更します。若い世代のサイズはG1が一時停止時間を満たすことを可能にする主要な手段であるため、-Xmn、-XX:NewRatioなどのオプションを使用することによって若い世代のサイズを特定の値に制限することを回避します。若い世代のサイズを単一の値に設定すると、一時停止時間の制御をオーバーライドし、実際に無効化します。

他のコレクタからG1への移行

一般的に、他のコレクタ、特にコンカレント・マーク・スイープ・コレクタからG1に移行する際に、ガベージ・コレクションに影響するオプションをすべて削除して開始し、-Xmxとオプションで-Xmsを使用して、一時停止時間目標と全体のヒープ・サイズのみを設定します。

特定の方法で応答する他のコレクタに便利な多数のオプションは、まったく影響を及ぼさないか、スループットを低減するか、一時停止時間ターゲットを満たす可能性を小さくします。たとえば、若い世代のサイズを設定して、一時停止時間目標を満たすようにG1が若い世代のサイズを調整しないようにできます。

G1パフォーマンスの向上

G1は、追加のオプションを指定することなく、全体的に適切なパフォーマンスを提供するように設計されています。ただし、デフォルトのヒューリスティックまたはデフォルト構成が最適以下の結果になる場合があります。この項では、これらの場合における診断および改善に関するガイドラインを示します。このガイドでは、特定のアプリケーションの場合の、選択したメトリックにおいてガベージ・コレクタのパフォーマンスを向上させるためにG1が提供する可能性についてのみ説明します。場合によっては、アプリケーションレベルの最適化のほうが、(寿命が長くないオブジェクトでの問題のある状況の回避など)パフォーマンスを改善するようにVMをチューニングするよりも効果的なことがあります。

診断目的で、G1では包括的なロギングを提供しています。-Xlog:gc*=debugオプションを使用して、必要に応じて出力を調整することをお薦めします。ログでは、ガベージ・コレクション・アクティビティの一時停止中および一時停止外の詳細情報が提示されます。これには、コレクションのタイプおよび一時停止の特定のフェーズに費やされた時間の内訳が含まれています。

次の項で、共通のパフォーマンスの問題について説明します。

フル・ガベージ・コレクションの監視

フル・ヒープ・ガベージ・コレクション(フルGC)は、時間がかかることがあります。古い世代の高いヒープ占有率によって発生したフルGCは、ログ内の一時停止のフル(割当ての失敗)を見つけることにより、検出できます。通常、フルGCの前に、to-space exhaustedタグで示される退避の失敗が発生したガベージ・コレクションが発生します。

フルGCが発生する理由は、回収できなくなるほど多数のオブジェクトをアプリケーションが割り当てるためです。コンカレント・マーキングは領域回収フェーズの開始に間に合うように完了できないことがあります。フルGCに移行する確率は、多数の大型オブジェクトの割当てにより大きくなることがあります。G1におけるこれらのオブジェクトの割当て方法よっては、想定よりも時間がかかることがあります。

目標は、コンカレント・マーキングが時間どおりに終了することを確認するためのものです。これを実現するには、古い世代の割当て率を減らすか、コンカレント・マーキングの完了に時間をかけるようにします。

G1には、このような状況により適切に対処するためのオプションがいくつかあります。

- Javaヒープに大型オブジェクトが多数存在する場合、gc+heap=infoロギングで大型リージョンの横に数値が表示されます。最適なオプションは、ガベージ・コレクション後にオブジェクトの数を減らそうとすることです。これを実現するには、 -XX:G1HeapRegionSizeオプションを使用してリージョン・サイズを増やします。現在選択されたヒープ・リージョン・サイズは、ログの開始時に出力されます。

- Javaヒープのサイズを増やします。これは、通常、マーキングが完了する必要がある時間を増やします。

- -XX:ConcGCThreadsを明示的に設定して、コンカレント・マーキング・スレッド数を増やします。

- G1でマーキングを早く開始するように強制します。G1では、より早いアプリケーションの動作に基づいた開始ヒープ占有率(IHOP)しきい値を自動的に判定します。アプリケーションの動作が変化すると、これらの予測が当てはまらない場合があります。2つのオプションがあります: -XX:G1ReservePercentを変更して適応型IHOPの計算で使用されるバッファを増やすことにより、領域回収の開始タイミング用にターゲット占有率を低くするか、-XX:-G1UseAdaptiveIHOPと-XX:InitiatingHeapOccupancyPercentを使用して手動設定により、IHOPの適応型計算を無効にします。

割当て失敗以外の原因によるフルGCの発生は、通常、アプリケーションまたは一部の外部ツールがフル・ヒープ・コレクションの原因であることを示します。原因がSystem.gc()であり、アプリケーション・ソースを変更できない場合、フルGCの影響は-XX:+ExplicitGCInvokesConcurrentを使用すると、低減できます。あるいは、-XX:+DisableExplicitGCを設定すると、VMにこれらを完全に無視させることもできます。外部ツールはフルGCを強制することがあります。これらを削除するには、フルGCをリクエストしないようにします。

大型オブジェクトの断片化

連続的なリージョン・セットを見つける必要があるため、すべてのJavaヒープ・メモリーが枯渇する前に、フルGCが発生することがあります。この場合に考えられるオプションは、オプション-XX:G1HeapRegionSizeを使用してヒープ・リージョン・サイズを増やして大型オブジェクト数を減らすか、ヒープ・サイズを増やすことです。極端な場合、使用可能なメモリーが十分にあっても、G1がオブジェクトを割り当てるのに使用可能な連続的な領域が十分にない可能性があります。これにより、フルGCで連続的な領域を十分に回収できないと、VMが終了します。したがって、前述のように、大型オブジェクトの割当て量を減らすか、ヒープを増やす以外の選択肢はありません。

レイテンシのためのチューニング

この項では、一時停止時間が長すぎるなど、共通のレイテンシの問題がある場合に、G1動作を改善するヒントについて説明します。

通常と異なるシステムまたはリアル・タイムの使用状況

ガベージ・コレクションの一時停止ごとに、gc+cpu=infoのログ出力には、一時停止時間中に費やされた時間の内訳とともにオペレーティング・システムの情報を記載する行が含まれています。このような出力の例は、User=0.19s Sys=0.00s Real=0.01sです。

ユーザー時間はVMコードで費やされた時間で、システム時間はオペレーティング・システムで費やされた時間で、リアル・タイムは一時停止時に経過した絶対時間です。システム時間が比較的高い場合、たいていは環境に原因があます。

システム時間が長い場合の共通の既知の問題は、次のとおりです。

- VMがオペレーティング・システムのメモリーからメモリーを割り当てたり、戻したりすると、不要な遅延が発生することがあります。遅延を回避するには、オプション-Xmsと -Xmxを使用して最小および最大ヒープ・サイズを同じ値に設定し、-XX:+AlwaysPreTouchを使用してすべてのメモリーをプレタッチしてこの作業をVM起動フェーズに移動します。

- 特にLinuxでは、透過的huge pages (THP)機能によって小さなページを大きなページに結合すると、一時停止時だけでなく、ランダムにプロセスの速度が低下することがあります。VMが大量のメモリーを割り当てたり保持したりするため、長時間VMの処理速度が低下するリスクが通常よりも高くなります。透過的huge pages機能を無効にする方法は、オペレーティング・システムのドキュメントを参照してください。

- ログ出力に書き込むと、ログが書き込まれるハード・ディスクのすべてのI/O帯域幅を断続的に占有するバックグラウンド・タスクのためにしばらくの間速度が低下することがあります。ログまたは他のストレージ(メモリー指定されたファイル・システムなど)に別のディスクを使用して、これを回避することを検討してください。

リアル・タイムが他の合計時間よりも長くなる場合がありますが、これは、過負荷になった可能性のあるマシンで十分なCPU時間をVMが得られなかったことを示すことがあります。

処理に長時間かかる参照オブジェクト

参照オブジェクトの処理にかかる時間に関する情報は、Ref ProcおよびRef Enqフェーズに示されています。Ref Procフェーズ時に、G1では特定タイプの要件に従って、参照オブジェクトの参照を更新します。Ref Enqでは、参照が無効になると、G1は参照オブジェクトを各参照キューに入れます。これらのフェーズで時間がかかりすぎる場合、オプション-XX:+ParallelRefProcEnabledを使用して、これらのフェーズの並列化を有効にすることを検討します。

時間がかかりすぎる若い世代のみのコレクション

若い世代のみのコレクション、すなわち一般的に若いコレクションは、若い世代のサイズ(具体的に言うと、コピーする必要のあるコレクション・セット内のライブ・オブジェクト数)に比例して時間がかかります。退避コレクション・セットフェーズが特にオブジェクト・コピー・サブフェーズで時間がかかりすぎる場合、-XX:G1NewSizePercentを減らします。これによって若い世代の最小サイズが小さくなり、一時停止が短くなる可能性があります。

アプリケーション・パフォーマンスや、特にコレクションを経て存続するオブジェクトの量が突然変化した場合、若い世代のサイズに関する別の問題が発生することがあります。これによって、ガベージ・コレクションの一時停止時間が大幅に増加する場合があります。-XX:G1MaxNewSizePercentを使用すると、若い世代の最大サイズの削減に役立つ場合があります。これは若い世代の最大サイズおよび一時停止時に処理する必要のあるオブジェクト数を制限します。

時間がかかりすぎる混合コレクション

混合コレクションは、古い世代の領域を回収する際に使用します。混合コレクションのコレクション・セットには若い世代と古い世代のリージョンが含まれています。gc+ergo+cset=traceログ出力を有効にすると、若い世代または古い世代のいずれかのリージョンの退避が一時停止時間に影響した時間に関する情報を取得できます。若い世代および古い世代のリージョンについては、それぞれ予測した若いリージョン時間と予測した古いリージョン時間を確認します。

予測した若い世代のリージョン時間が長すぎる場合、オプションは、「時間がかかりすぎる若い世代のみのコレクション」を参照してください。これ以外の場合、古い世代のリージョンの一時停止時間への影響を少なくするために、G1では次の3つのオプションを提供しています。

- -XX:G1MixedGCCountTargetを増やして、さらに多くのガベージ・コレクションで古い世代のリージョンの回収を拡大します。

- -XX:G1MixedGCLiveThresholdPercentを使用して、リージョンを候補コレクション・セットに移動しないで、収集に比例的に時間がかかるリージョンを収集しないようにします。多くの場合、多く占有しているリージョンは収集に時間がかかります。

- G1が多く占有しているリージョンを多数収集しないように、古い世代の領域回収を早めに停止します。この場合、 -XX:G1HeapWastePercentを増やします。

最後の2つのオプションは、現在の領域回収フェーズで領域を回収できる、コレクション・セットの候補リージョンの量を減らすことに注意してください。これは、持続した操作に対して古い世代の十分な領域をG1で回収できないことがあるという意味です。ただし、後の領域回収フェーズで、これらに対してガベージ・コレクションを実行できます。

高いRSの更新およびRSのスキャン時間

G1を有効にして古い世代のリージョンを退避させるには、G1ではリージョン間参照(リージョン間で相互に指す参照)の場所をトラッキングします。特定のリージョンを指すリージョン間参照のセットは、リージョンの記憶済セットと呼ばれます。記憶済セットは、リージョンの内容を移動する際に更新する必要があります。リージョンの記憶済セットの保守は、モーストリ・コンカレントです。アプリケーションが2つのオブジェクト間で新しいリージョン間参照を組み込んだとき、パフォーマンスのために、G1ではリージョンの記憶済セットを即座に更新しません。記憶済セットの更新リクエストは、効率性を高めるために遅延され、一括で実行されます。

G1ではガベージ・コレクションに完全な記憶済セットが必要であるため、ガベージ・コレクションのRSの更新フェーズでは未処理の記憶済セットの更新リクエストを処理します。RSのスキャン・フェーズにおいて記憶済セット内のオブジェクト参照を検索し、リージョンの内容を移動してから、これらのオブジェクト参照を新しい場所に更新します。アプリケーションによっては、これらの2つのフェーズではかなり時間がかかることがあります。

オプション-XX:G1HeapRegionSizeを使用してヒープ・リージョンのサイズを調整すると、リージョン間参照数と記憶済セットのサイズに影響があります。リージョンの記憶済セットの処理はガベージ・コレクション作業のかなりの部分を占めることがあるので、これは、達成可能な最大一時停止時間に直接影響を及ぼします。リージョンが大きくなると、リージョン間参照の数は少なくなるので、これらの処理に費やされる相対的な作業量が減少します。ただし、同時に、大きなリージョンはリージョンごとに退避するライブ・オブジェクトが増え、他のフェーズの時間が増加します。

G1では記憶済セットの更新の同時処理をスケジュールしようとするため、RSの更新フェーズは、許可された最大一時停止時間に対して約-XX:G1RSetUpdatingPauseTimePercentパーセントの時間がかかります。この値を減らすと、通常、G1はより多くの記憶済セットの更新作業を同時に実行します。

大きなオブジェクトを割り当てるアプリケーションと組み合せた、不要に高いRSの更新時間は、一括実行によって記憶済セットの同時更新作業を減らそうとする最適化によって発生することがあります。このような一括実行で作成されたアプリケーションがガベージ・コレクションの直前に発生した場合、ガベージ・コレクションはこの作業のすべてを一時停止のRSの更新時間部分で処理する必要があります。-XX:-ReduceInitialCardMarksを使用して、この動作を無効にし、このような状況を回避します。

RSのスキャン時間は、G1が記憶済セットのストレージ・サイズを小さくするために実行する圧縮量によっても決定されます。記憶済セットがメモリーに圧縮されて格納されると、ガベージ・コレクション時に格納された値の取得に時間がかかります。G1ではこのような圧縮(記憶済セットの粗大化と呼ぶ)を自動的に実行しますが、記憶済セットの更新はリージョンの記憶済セットの現在のサイズによって異なります。特に最も高い圧縮レベルでは、実際のデータの取得の処理速度が非常に遅くなることがあります。gc+remset=traceレベルのロギングと組み合せたオプション-XX:G1SummarizeRSetStatsPeriodでは、この粗大化が発生したかどうかを示します。この場合、Before GC SummaryセクションのDid <X> coarsenings行のXは高い値を示します。-XX:G1RSetRegionEntriesオプションの値を大幅に増やして、これらの粗大化の量を減らすことができます。このデータの収集に長時間かかることがあるため、本番環境でこの詳細な記憶済セットのロギングを使用しないでください。

スループットのためのチューニング

G1のデフォルト・ポリシーはスループットとレイテンシ間でバランスを取ろうとしますが、より高いスループットが望ましい場合があります。前述の項で説明した全体的な一時停止時間の短縮とは別に、一時停止の頻度を減らすことができます。これには、-XX:MaxGCPauseMillisを使用して最大一時停止時間を増やします。世代のサイズ設定のヒューリスティックでは自動的に若い世代のサイズを適応させ、これにより、一時停止の頻度を直接判定します。これによって期待したように動作しない場合、特に領域回収フェーズで、-XX:G1NewSizePercentを使用して若い世代の最小サイズを増やして、G1でこれを実行するように強制します。

場合によっては、若い世代の最小許容サイズの-XX:G1MaxNewSizePercentで若い世代のサイズを制限することにより、スループットを制限できます。gc+heap=infoロギングのリージョン・サマリー出力で確認することにより、これを診断できます。ここで、EdenリージョンとSurvivorリージョンを組み合せた割合は、リージョンの合計値の-XX:G1MaxNewSizePercentパーセントに近くなります。この場合、-XX:G1MaxNewSizePercentを増やすことを検討してください。

スループットを増やす別のオプションは、同時作業の量を減らそうとすることです。特に記憶済セットの同時更新は、大量のCPUリソースが必要になることがあります。-XX:G1RSetUpdatingPauseTimePercentを増やすと、作業が同時操作からガベージ・コレクションの一時停止に移動します。最悪の場合、-XX:-G1UseAdaptiveConcRefinement -XX:G1ConcRefinementGreenZone=2G -XX:G1ConcRefinementThreads=0を設定して、記憶済セットの同時更新を無効にできます。これにより、このメカニズムを無効にして、すべての記憶済セット更新作業を次のガベージ・コレクションの一時停止に移行します。

-XX:+UseLargePagesを使用して大きなページの使用を有効にして、スループットを向上させることもできます。大きなページの設定方法は、ご使用のオペレーティング・システムのマニュアルを参照してください。

これを無効にすると、ヒープのサイズ変更作業を最小化でき、オプション-Xmsと-Xmxを同じ値に設定します。さらに、-XX:+AlwaysPreTouchを使用して、オペレーティング・システムによる仮想メモリーと物理メモリーの作業をVMの起動時に移動します。これらの両方の措置は、一時停止をより一貫したものにするために特に望ましい場合があります。

ヒープ・サイズのためのチューニング

他のコレクタと同様に、G1では、ガベージ・コレクションで費やされる時間が-XX:GCTimeRatioオプションで決定される比率を下回るように、ヒープのサイズを設定しようとします。このオプションを調整して、G1がユーザーの要件を満たすようにします。

チューニング可能なデフォルト設定

この項では、このトピックで紹介されているコマンド行オプションのデフォルト値と追加情報について説明します。

表10-1 G1 GCのチューニング可能なデフォルト設定

オプションとデフォルト値

説明

-XX:+G1UseAdaptiveConcRefinement

-XX:G1ConcRefinementGreenZone=<ergo>

-XX:G1ConcRefinementYellowZone=<ergo>

-XX:G1ConcRefinementRedZone=<ergo>

-XX:G1ConcRefinementThreads=<ergo>

記憶済セットの同時更新(調整)では、これらのオプションを使用して、同時調整スレッドの作業の分散を制御します。G1では、これらのオプションにエルゴノミックな値を選択することにより、-XX:G1RSetUpdatingPauseTimePercent時間が、ガベージ・コレクションの一時停止で費やされ、残りの作業を処理し、適応させながら必要に応じてこれらを調整します。これによって極端な長い一時停止になることがあるため、慎重に変更してください。

-XX:+ReduceInitialCardMarks

これは、初期オブジェクトの割当てのために記憶済セットの同時実行(調整)作業を一括実行します。

-XX:-ParallelRefProcEnabled

これは、java.lang.Ref.*インスタンスの処理を複数のスレッドで並行で実行するかどうかを判定します。

-XX:G1RSetUpdatingPauseTimePercent=10

これは、残りの記憶済セットを更新するRSの更新フェーズでG1が費やす必要があるガベージ・コレクションの合計時間の割合を判定します。G1では、この設定を使用して、記憶済セットの同時更新の量を制御します。

-XX:G1SummarizeRSetStatsPeriod=0

これは、G1が記憶済セットのサマリー・レポートを生成する、多数のGCにおける期間です。無効にするには、これをゼロに設定します。記憶済セットのサマリー・レポートの生成はコストのかかる操作であるため、必要な場合にのみ、かなり高い値を設定してこれを使用してください。出力するには、gc+remset=traceを使用します。

-XX:GCTimeRatio=12

これは、アプリケーションとは対照的に、ガベージ・コレクションで費やす必要がある時間の対象となる比率の除数です。ヒープを増やす前にガベージ・コレクションで費やすことができる時間の小数を判定するための実際の式は、1 / (1 + GCTimeRatio)です。このデフォルト値は、ガベージ・コレクションで費やされる時間の約8%の目標値になります。

注意:
<ergo>は、実際の値が環境によってエルゴノミックに決定されるという意味です。

11 その他の考慮事項

この項では、ガベージ・コレクションに影響するその他の状況について説明します。

トピック

- ファイナライズと弱参照、ソフト参照およびファントム参照

- 明示的なガベージ・コレクション

- ソフト参照

- クラス・メタデータ

ファイナライズと弱参照、ソフト参照およびファントム参照

一部のアプリケーションは、ファイナライズと弱参照、ソフト参照またはファントム参照を使用してガベージ・コレクションと相互作用します。

これらの機能は、Javaプログラミング言語のレベルでパフォーマンスに悪影響を与える可能性があります。たとえば、ファイナライズによってファイル記述子を閉じると、外部リソース(記述子)がガベージ・コレクションの機敏性に依存するようになります。ガベージ・コレクションにメモリー以外のリソースを管理させることは、通常はお薦めできません。

Javaファイナライズのメモリー保持問題の対処方法に関する項を参照してください。ここでは、ファイナライズの問題とこれを回避する技術について詳細に説明しています。

明示的なガベージ・コレクション

アプリケーションがガベージ・コレクションと相互作用できるもう1つの方法は、System.gc()を使用して、すべてのガベージ・コレクションを明示的に呼び出す方法です。

これを行うと、必要ない場合(たとえば、マイナー・コレクションで十分な場合)でもメジャー・コレクションの実行が強制されるので、通常は使用しないことをお薦めします。明示的なガベージ・コレクションによるパフォーマンスへの影響を測定するには、フラグ-XX:+DisableExplicitGCを使用してVMにSystem.gc()のコールを無視させ、明示的なガベージ・コレクションを無効にします。

明示的なガベージ・コレクションが最もよく使用される例の1つが、リモート・メソッド呼出し(RMI)の分散ガベージ・コレクション(DGC)です。RMIを使用するアプリケーションは、他の仮想マシンのオブジェクトを参照します。これらの分散アプリケーションでは、ローカル・ヒープのガベージ・コレクションを時々呼び出さないとガベージを収集できないので、RMIがフル・コレクションを定期的に実行します。これらのコレクションの実行間隔はプロパティで制御できます(次の例を参照)。

java -Dsun.rmi.dgc.client.gcInterval=3600000
-Dsun.rmi.dgc.server.gcInterval=3600000 ...

この例では、明示的なガベージ・コレクションの実行間隔をデフォルトの1回/分ではなく、1回/時間に指定します。ただし、これでも一部のオブジェクトが回収されるまでに長時間かかる場合があります。DGCのタイムリな処理に上限を設定する必要なければ、これらのプロパティの値をLong.MAX_VALUEまで引き上げ、明示的なコレクションの時間間隔を事実上無限大にすることができます。

ソフト参照

サーバー仮想マシンでは、ソフト参照がクライアント仮想マシンよりも長くライブに保たれます。

クリア間隔を制御するには、コマンド行オプション-XX:SoftRefLRUPolicyMSPerMB=<N>を使用して、ソフト参照を(強到達可能ではなくなってから)ライブに保つ期間を、ヒープ内の空き領域1MB当たりのミリ秒(ms)で指定します。デフォルト値は1000ms/MBで、これは、(オブジェクトへの最後の強参照が収集された後の)ソフト参照がヒープ内の空き領域1MB当たり1秒の寿命であることを意味します。ソフト参照は、散発的に発生するガベージ・コレクション時にのみクリアされるので、これは概算値です。

クラス・メタデータ

JavaクラスにはJava Hotspot VM内の内部表現があり、それはクラス・メタデータと呼ばれます。

以前のリリースのJava Hotspot VMで、クラス・メタデータはPermanentと呼ばれる永続的世代に割り当てられていました。JDK 8以降、永続的(Permanent)世代が削除され、クラス・メタデータがネイティブ・メモリーに割り当てられます。クラス・メタデータに使用できるネイティブ・メモリーの容量はデフォルトで無制限です。クラス・メタデータに使用するネイティブ・メモリーの容量に上限を設定するには、オプション-XX:MaxMetaspaceSizeを使用します。

Java Hotspot VMではメタデータ用の領域を明示的に管理します。OSから領域が要求され、その領域がチャンクに分割されます。そのチャンクからクラス・ローダーがメタデータに領域を割り当てます(チャンクは特定のクラス・ローダーにバインドされます)。クラス・ローダーのクラスがアンロードされると、そのチャンクは再利用に回されるか、OSに返されます。メタデータは、mallocではなくmmapによって割り当てられた領域を使用します。

-XX:UseCompressedOopsをオンにして-XX:UseCompressedClassesPointersを使用する場合、ネイティブ・メモリーの論理的に異なる2つの領域がクラス・メタデータに使用されます。-XX:UseCompressedClassPointersは、Javaオブジェクト参照の場合の-XX:UseCompressedOopsと同様に、32ビットのオフセットを使用してクラス・ポインタを64ビットプロセスで表現します。このような圧縮クラス・ポインタにリージョンが割り当てられます(32ビット・オフセット)。リージョンのサイズは-XX:CompressedClassSpaceSizeで設定でき、デフォルトは1ギガバイト(GB)です。圧縮クラス・ポインタの領域は、初期化時に-XX:mmapによって割り当てられた領域として確保され、必要に応じてコミットされます。-XX:MaxMetaspaceSizeは、コミットされた圧縮クラスの領域と他のクラス・メタデータの領域の合計に適用されます。

クラス・メタデータは対応するJavaクラスのアンロード時に割当て解除されます。Javaクラスはガベージ・コレクションに伴ってアンロードされるので、クラスのアンロードとクラス・メタデータの割当て解除を行うためにガベージ・コレクションが誘発される場合があります。クラス・メタデータ用にコミットされた領域が一定のレベル(最高水位標)に到達すると、ガベージ・コレクションが発生します。ガベージ・コレクション後、クラス・メタデータから解放された領域量に応じて、最高水位標が上げられたり、下げられたりすることがあります。別のガベージ・コレクションがすぐに発生しないように、最高水位標は上げられます。最高水位標の初期値は、コマンド行オプション-XX:MetaspaceSizeの値に設定されます。-XX:MaxMetaspaceFreeRatioオプションと-XX:MinMetaspaceFreeRatioオプションを基に、これを上げ/下げします。クラス・メタデータで使用可能なコミットされた領域(クラス・メタデータ用にコミットされた総領域の割合)が-XX:MaxMetaspaceFreeRatioより大きいと、最高水位標は下げられます。これが-XX:MinMetaspaceFreeRatioより低いと、最高水位標は上げられます。

クラス・メタデータによるガベージ・コレクションの早期誘発を避けるには、オプション-XX:MetaspaceSizeに高めの値を指定します。アプリケーションに割り当てられるクラス・メタデータの容量はアプリケーションに依存するので、 -XX:MetaspaceSizeの選択に一般的なガイドラインはありません。-XX:MetaspaceSizeのデフォルト・サイズは、12MBから約20MBの範囲でプラットフォームに依存します。

メタデータに使用される領域に関する情報はヒープの出力に含まれます。出力は、通常次のようになります。

[0,296s][info][gc,heap,exit] Heap
[0,296s][info][gc,heap,exit] garbage-first heap total 514048K, used 0K [0x00000005ca600000, 0x00000005ca8007d8, 0x00000007c0000000)
[0,296s][info][gc,heap,exit] region size 2048K, 1 young (2048K), 0 survivors (0K)
[0,296s][info][gc,heap,exit] Metaspace used 2575K, capacity 4480K, committed 4480K, reserved 1056768K
[0,296s][info][gc,heap,exit] class space used 238K, capacity 384K, committed 384K, reserved 1048576K

「Metaspace」で始まる行のused値は、ロード済クラスが使用している領域量です。capacity値は、現在割り当てられているチャンク内のメタデータで使用可能な領域です。committed値は、チャンクの使用可能な領域量です。reserved値は、メタデータ用に確保された(必ずしもコミットされているとはかぎらない)領域量です。class spaceで始まる行には、圧縮クラス・ポインタのメタデータの対応する値が含まれています。

Oracleの法律上の注意点

コピーライト

Copyright © 1994-2018, Oracle and/or its affiliates. All rights reserved.

ライセンス制約の保証と結果的に生じる損害の免責

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

保証免責

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクルまでご連絡ください。

制限付権利について

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs. No other rights are granted to the U.S. Government.

危険な用途への使用について

このソフトウェアまたはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアまたはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、Oracle Corporationおよびその関連会社は一切の責任を負いかねます。

商標と登録商標について

OracleおよびJavaはオラクルおよびその関連会社の登録商標です。その他の社名、商品名等は各社の商標または登録商標である場合があります。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

第三者のコンテンツ、製品、サービスに対する免責事項

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。適用されるお客様とOracle Corporationとの間の契約に別段の定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。適用されるお客様とOracle Corporationとの間の契約に定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

Pre-General Availability (一般提供前)版のドキュメントについて

このドキュメントがPre-General Availability (一般提供前)版の場合:

このドキュメントはPre-General Availability (一般提供前)版であり、デモおよび暫定使用のみを目的としたものです。このソフトウェアを使用するハードウェアに限定するものではありません。Oracle Corporationおよびその関連会社は、このドキュメントに関して一切の責任を負わず、いかなる保証もいたしません。また、このドキュメントを使用したことによって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

非公開のPre-General Availability (一般提供前)版のドキュメントについて

このドキュメントが非公開のPre-General Availability (一般提供前)版の場合:

このドキュメントに含まれる情報は、情報の共有のみを目的としたものであって、顧客諮問委員会(Customer Advisory Board)のメンバーとしてのお客様の立場でのみ、またはお客様のPre-General Availability Trial Agreement (Pre-GAトライアル契約)のみに従って検討されるべきものとします。マテリアル、コード、または機能の提供をお約束するものではなく、購入決定を行う際の判断材料とすべきではありません。このドキュメントに記載されている特徴または機能の開発、リリースおよび時期については、オラクルの裁量により決定されます。

このドキュメントには、ソフトウェアまたは印刷物などの形式を問わず、オラクルが独占的な権利を有する財産的情報が含まれています。この機密資料へのアクセスと使用は、お客様とオラクルとの間で締結され、お客様が遵守に同意した、Oracle Master Agreement、Oracle License and Oracle Services Agreement (オラクル・ライセンスおよびサービスに関する契約書)、Oracle Partner Network Agreement、Oracle Distribution Agreementまたはその他のライセンス契約の条件に従うものとします。このドキュメントとその内容の開示、コピー、複製および配布には、オラクルによる事前の承諾を必要とします。このドキュメントはライセンス契約の一部となるものではなく、オラクルおよびその子会社や関連会社との契約を構成するものではありません。

ドキュメントのアクセシビリティ

オラクルのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイト(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc)を参照してください。

Oracle Supportへのアクセス

サポートをご契約のお客様には、My Oracle Supportを通して電子支援サービスを提供しています。詳細情報は(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info)か、聴覚に障害のあるお客様は(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs)を参照してください。