4 クラス・データ共有

この章では、Javaアプリケーションの起動時間とメモリー・フットプリントの削減に役立つクラス・データ共有(CDS)機能について説明します。

クラス・データ共有

クラス・データ共有(CDS)機能は、複数のJava仮想マシン(JVM)間の起動時間とメモリー・フットプリントの削減に役立ちます。

JDK 12以降、デフォルトCDSアーカイブはOracle JDKバイナリに事前パッケージ済です。デフォルトCDSアーカイブは、G1 GCおよび128MのJavaヒープを使用し、-Xshare:dumpを実行して、JDKのビルド時に作成されます。ビルド時に生成されたデフォルトのクラス・リスト(選択したコア・ライブラリ・クラスが含まれる)が使用されています。デフォルトCDSアーカイブは、次の場所に存在します。
  • LinuxおよびmacOSプラットフォームの場合、共有アーカイブは/lib/[arch]/server/classes.jsaに格納されます

  • Windowsプラットフォームの場合、共有アーカイブは/bin/server/classes.jsaに格納されます

デフォルトでは、デフォルトCDSアーカイブは実行時に有効化されます。デフォルトの共有アーカイブを無効化するには、-Xshare:offを指定します。カスタム共有アーカイブを作成するには、「共有アーカイブの再生成」を参照してください。カスタム共有アーカイブを作成して使用している場合は、ダンプ時と実行時の両方で同じJavaヒープ・サイズを使用してください。

JVMを開始すると、共有アーカイブがメモリー・マッピングされ、これらのクラス用の読取り専用のJVMメタデータを複数のJVM処理で共有できます。共有アーカイブへのアクセスは、クラスのロードよりも高速であるため、起動時間が短縮されます。

クラス・データ共有は、ZGC、G1、シリアルおよびパラレル・ガベージ・コレクタでサポートされています。共有Javaヒープ・オブジェクト機能(クラス・データ共有の一部)では、64ビットの非Windowsプラットフォーム上のG1ガベージ・コレクタのみがサポートされています。

CDSをJava SEに含める主要な動機は、起動時間の短縮です。使用するコア・クラスの数に比べてアプリケーションが小さいほど、起動時間の節約比率が大きくなります。

新規JVMインスタンスのフットプリント・コストは、2つの方法で削減されています。
  1. 同一のホスト上の共有アーカイブの一部が読取り専用としてマップされ、複数のJVM処理で共有されます。それ以外の場合、このデータは各JVMインスタンス内でレプリケートされる必要があるため、アプリケーションの起動時間が長くなります。

  2. 共有アーカイブに、Java Hotspot VMが使用できる形式でクラス・データが格納されます。他の場合はランタイム・モジュラ・イメージの元のクラス情報にアクセスするためにメモリーが必要になりますが、この場合は使用されません。これらのメモリーの節約により、同じシステム上でより多くのアプリケーションを同時に実行できます。Windowsアプリケーションでは、プロセスのメモリー・フットプリント(様々なツールで測定)が増えたように見える場合があります。これは、プロセスのアドレス空間にマッピングされるページが増えるためです。この増加は、ランタイム・モジュラ・イメージに対して保持する必要があるメモリーの量(Windows内)が減ることによって相殺されます。フットプリントの削減は、依然として優先度の高い課題です。

アプリケーション・クラス・データ共有

起動時間およびフットプリントをさらに削減するために、アプリケーション・クラス・パスからの選択済クラスを含めるようにCDS拡張する、アプリケーション・クラス・データ共有(AppCDS)が導入されました。

この機能により、アプリケーション・クラスを共有ドライブに配置できます。共通のクラス・メタデータは、異なるJavaプロセスで共有されます。AppCDSにより、組込みシステム・クラス・ローダー、組込みプラットフォーム・クラス・ローダーおよびカスタム・クラス・ローダーで、アーカイブ済のクラスをロードできるようになります。複数のJVMが同じアーカイブ・ファイルを共有している場合、メモリーは保存され、システムの全体的なレスポンス時間が向上します。

Java Development Kitツール仕様アプリケーション・クラス・データ共有に関する項を参照してください。

動的CDSアーカイブ

動的CDSアーカイブは、アプリケーション・クラスデータ共有(AppCDS)を拡張して、Javaアプリケーションの終了時にクラスの動的アーカイブを可能にします。

試行の実行を排除して各アプリケーションのクラス・リストを作成することで、AppCDSの使用を簡略化します。アーカイブされたクラスには、ロードされているすべてのアプリケーション・クラスと、デフォルトCDSアーカイブに存在しないライブラリ・クラスが含まれます。

動的CDSアーカイブを作成するには、コマンド-XX:+RecordDynamicDumpInfoを使用してJavaアプリケーションを起動します。このフラグを-XX:ArchiveClassesAtExitとともに使用しないでください。

『Java Development Kitツール仕様』「CDSアーカイブの使用」を参照してください。

共有アーカイブの再生成

サポートされているすべてのプラットフォームに対して共有アーカイブを再生成できます。

JDKとともにインストールされるデフォルト・クラス・リストには、コア・ライブラリ・クラスの小さいセットのみが含まれます。共有アーカイブに他のクラスを含めることもできます。デフォルトCDSアーカイブをベース・アーカイブとして使用して動的CDSアーカイブを作成するには、次のコマンドでJavaアプリケーションを起動します:

-XX:+RecordDynamicDumpInfo

動的に生成された個別のアーカイブが、アプリケーションごとにデフォルト・システムの上部に作成されます。動的アーカイブの名前は、jcmd <pid or AppName> VM.cds dynamic_dump <filename>コマンドの引数として指定できます。ファイル名を指定しない場合、デフォルトのファイル名java_pid<number>_dynamic.jsaが生成されます(<number>はプロセスIDです)。

アーカイブ・ファイルを再生成するには、管理者としてログインします。ネットワークに接続している場合は、Java SEインストールと同じアーキテクチャのコンピュータにログインします。インストール・ディレクトリに対する書込み権限を持っていることを確認してください。

ユーザー定義のクラス・リストを使用して共有アーカイブを再生成するには、次のコマンドを入力します。

jcmd <pid or AppName> VM.cds <subcommand> <filename>

アーカイブが生成されると、診断情報が出力されます。

手動によるクラス・データ共有の制御

クラス・データ共有はデフォルトで有効になっています。この機能は手動で有効と無効を切り替えることができます。

診断およびデバッグのために、次のコマンドライン・オプションを使用できます。

-Xshare:off
クラス・データ共有を無効にする場合。
-Xshare:on
クラス・データ共有を有効にする場合。クラス・データ共有を有効にできない場合は、エラー・メッセージを出力して終了します。

ノート:

-Xshare:onは、テスト目的でのみ使用します。CDSアーカイブを使用できない場合(たとえば、特定のVMパラメータが変更された場合や、別のJDKが使用されている場合)、起動時にVMが予期せず終了することがあります。このオプションは、本番環境では使用しないでください。
-Xshare:auto
クラス・データ共有をデフォルトで有効にする場合。可能な場合は常にクラス・データ共有を有効にします。

CDSアーカイブの自動生成

コマンド-XX:+AutoCreateSharedArchiveを使用して、動的なCDSアーカイブ・ファイルを自動的に作成できます。たとえば:
java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=app.jsa -cp app.jar
    App

指定されたアーカイブ・ファイルが作成されるのは、そのファイルが存在しない場合、またはファイルが別のJDKバージョンによって生成されている場合です。

『Java Development Kitツール仕様』「-XX:+AutoCreateSharedArchiveによる動的CDSアーカイブ・ファイルの作成」を参照してください。