- JDK 23 用 GraalVM (最新)
- JDK 24 用 GraalVM (早期アクセス)
- JDK 21 用 GraalVM
- JDK 17 用 GraalVM
- アーカイブ
- 開発ビルド
よくある質問
ユニットテストをプロファイリングに使用できますか? #
はい、可能ですが、通常はお勧めしません。ユニットテストを使用してプロファイルを生成するには、任意のアプリケーションのネイティブ実行可能ファイルを生成するのと同じ方法で、テストスイート用にインストルメント化されたバイナリを生成する必要があります。たとえば、テストハーネスを開始するmain()
メソッドを使用できます。インストルメント化されたバイナリが実行されると、インストルメント化されたバイナリと同様に、プロファイルを含むファイルがダンプされます。
プロファイルに基づく最適化の品質は、最適化されたネイティブビルドへの入力として提供するプロファイルの品質に依存することに注意してください。テストが、本番環境で実行されるワークロードを正確に表していることを確認する必要があります。一般的に、それを保証するのは簡単ではありません。なぜなら
- ユニットテストは、コンポーネントのすべてのコーナーケースをテストするように設計されており、その多くは実際には一般的ではありません(つまり、テストして正しく機能させる必要がありますが、コードのコーナーケースは通常、高速である必要はありません)。
- コードのさまざまなコンポーネントが、常に同じ数のユニットテストで表されるわけではありません。ユニットテストスイートに基づくプロファイルは、あるコンポーネントの重要性を過度に表し、他のコンポーネントの重要性を過小に表す場合があります。
- ユニットテストスイートは、ますます多くのテストが追加されるにつれて、時間の経過とともに進化します。今日、アプリケーションの動作を正確に表すものが、明日には正確に表さない可能性があります。
たとえば、静的コンテンツを提供するWebサーバーを実装しているとします。ほとんどの場合、Webサーバーはディスクまたはインメモリキャッシュからファイルを読み取り、そのファイルを圧縮し、圧縮されたバイトをネットワーク経由で送信します。ただし、適切なユニットテストスイートは、構成ファイル解析、キャッシュ無効化、リモートデバッグなどのコードを含む、Webサーバーのすべてのコンポーネントをテストします。これらは、Webサーバーの典型的な実行中に、実行頻度が低いか、まったく実行されない可能性があります。すべてのユニットテストでプロファイルを収集すると、実際には実行頻度が低いコードの部分が過度に表され、これにより、コンパイラの最適化が誤った方向に進んでしまいます。
結論として、これは可能ですが、ユニットテストがアプリケーションの動作をどの程度表しているか不明確であるため、ユニットテストをプロファイルとして使用することはお勧めしません。代わりに推奨するのは、次のいずれかです。
- 重要な本番ワークロードを表すエンドツーエンドテストのサブセットを特定します。エンドツーエンドテストは、アプリケーションが本番環境で実行する動作をシミュレートし、コード内で時間を使用する方法と場所を正しく描写する可能性が高くなります。上記のWebサーバーの例では、エンドツーエンドテストはWebサーバーを起動し、さまざまなURLを取得するために数千のリクエストを送信し、サーバーをシャットダウンします。
- または、アプリケーションが本番環境で行う動作を表すベンチマークワークロードを作成します。適切なベンチマークには、典型的なワークロードの特性が組み込まれます。上記のWebサーバーの例では、現実的なベンチマークは、Webサーバーが本番環境で実行されていたときに観察されたリクエストの分布を組み込みます。つまり、ベンチマークは、本番環境で特定のサイズのファイルが要求される頻度と、ファイルの圧縮率をモデル化します。
PGOプロファイルは十分にクロスプラットフォームですか、それとも各ターゲットを個別にインストルメント化する必要がありますか? #
はい、ほとんどの場合、PGOプロファイルは十分にクロスプラットフォームです。インストルメント化されたバイナリを1つのプラットフォームで実行してプロファイルを収集できますが、それらのプロファイルを使用して、別のプラットフォームで最適化されたネイティブ実行可能ファイルをビルドできます。
ネイティブイメージが、バイナリがビルドされたプラットフォームに応じて異なるクラスとメソッドを使用する場合があります。たとえば、PosixProcessPropertiesSupport
クラスには、POSIXベースのシステムでプロセスを操作するコードが含まれていますが、WindowsProcessPropertiesSupport
クラスには、Windowsでプロセスを操作するコードが含まれています。同様に、JDKの特定の部分には、プラットフォーム固有のコードが含まれています。これらの場合、プロファイルにはあるプラットフォームのエントリが含まれますが、最適化されたネイティブビルドでは、プラットフォーム固有のコードのプロファイルエントリが見つかりません。これらのコーナーケースはまれであり、通常はパフォーマンスに影響を与えませんが、注意しておくべきことです。
結論として、常に最適化されたネイティブ実行可能ファイルのターゲットと同じプラットフォームでプロファイルを収集することが最善の方法です。ただし、別のプラットフォームで収集されたプロファイルを使用しても、通常はうまく機能するはずです。
コード変更後にプロファイル情報を再利用できますか(コード変更が限定的な場合)、それともビルドごとに新しいプロファイル情報を収集する必要がありますか? #
はい、プロファイル情報は常に再利用でき、ネイティブ実行可能ファイルは正しく生成される必要があります。ビルドごとに新しいプロファイル情報を収集する必要はありません。
ただし、最適化されたネイティブ実行可能ファイルに対するパフォーマンスの影響は、プロファイルの品質に依存することに注意してください。プログラムの新しいコードが、プロファイルが収集されたコードから大きく逸脱している場合、コンパイラの最適化は、どのコードが重要であるかについて誤解します。コードの変更が十分に小さい場合、またはプログラムのコールド部分に限定されている場合、古いプロファイルを使用しても、通常、最適化されたネイティブバイナリのパフォーマンスが損なわれることはありません。
このトピックの詳細については、プロファイル品質の追跡ガイドラインをご覧ください。
インストルメント化されたバイナリでベンチマークを実行することもできますか? #
はい、インストルメント化されたバイナリは、ベンチマークを含む任意のプログラムに対して生成できます。実際、代表的なベンチマークを使用してプロファイルを収集することが、プロファイルを収集する推奨方法です。
インストルメンテーションのオーバーヘッドにより、インストルメント化されたバイナリは、デフォルトの(インストルメント化されていない)ネイティブ実行可能ファイルよりも通常遅くなることに注意してください。インストルメンテーションのオーバーヘッドを最小限に抑えるために常に努力していますが、インストルメント化されたバイナリが遅くなることに気づく可能性が高く、実行しているアプリケーションのコードパターンによって異なります。
また、ベンチマークは、本番環境で予想されるワークロードを代表するものであることが理想的であることに注意してください。ベンチマークのワークロードが本番ワークロードに対応するほど、PGOが最適化されたネイティブビルドにプラスのパフォーマンス影響を与える可能性が高くなります。
結論として、ベンチマークが本番環境で実行するワークロードを正確に表している場合、インストルメント化されたベンチマークバイナリでプロファイルを収集し、後でこれらのプロファイルを使用して、本番ワークロード用に最適化されたネイティブ実行可能ファイルをビルドすることをお勧めします。
GraalVMは、Webアプリケーションのプロファイリングのためにどのようにワークロードを生成しますか? #
GraalVM自体は、ネイティブイメージでコンパイルされたWebアプリケーションのプロファイリングのためにワークロードを生成しません。代わりに、ワークロードを生成するには、ロードテストツールを使用する必要があります。
たとえば、Webアプリケーションが複数のHTTPエンドポイントを公開している場合は、wrk
などのロードテスターを使用して、それらのHTTPエンドポイントへのリクエストストリームを生成する必要があります。この設定は次のようになります。Webアプリケーションのインストルメント化されたバイナリをビルドし、1つのプロセスで起動し、別のプロセスでwrk
などのロードテスターを起動します。ロードテストの期間は、本番ユーザーが最も頻繁にアクセスするWebアプリケーションのエンドポイントを、本番環境で遭遇すると予想されるリクエストペイロードを使用して、十分に実行するのに十分な長さである必要があります。単純なWebアプリケーションの場合、通常、1分の期間で適切な品質のプロファイルを生成するのに十分です(ただし、これは特定のアプリケーションによって異なります)。ロードテストが完了してWebアプリケーションが終了すると、プロファイルがファイルにダンプされます。
しばらくの間、本番環境でプロファイルを収集しないのはなぜですか? たとえば、月曜日の8:00から12:00まで、サービスの1つのインスタンスのみで収集します。 #
はい、それはプロファイルを収集するのに良い方法です。
インストルメント化されたバイナリには、特定のアプリケーションのコードパターンによって異なる特定のオーバーヘッドがあります。ただし、特定の期間中にインストルメント化されたバイナリを使用するインスタンスが1つだけで、サービスの他のすべてのインスタンスが通常またはPGO最適化されたビルドを使用している場合、これは一般的に実際には許容されます。
このトピックの詳細については、プロファイル品質の追跡ガイドラインをご覧ください。