最初の呼び出しが遅くなるのを避けるためにJavaクラスをウォームアップする方法は?


13

すべてのAPI呼び出しを1秒未満で実行する必要があるプロジェクトを実行していますが、各ルートへの最初の呼び出しで、次の呼び出しよりも遅い問題に直面しています。

現在、/ loginへの最初の呼び出しには3.6秒かかり、次の呼び出しには170ミリ秒かかり、他のすべてのルートで同じです。

-XX:+TraceClassLoading最初の呼び出しでそれを使用して、クラスがメモリにロードされ、パフォーマンスの問題を引き起こしたことがわかりました。

ただし、起動時にすべてのクラスをロードする簡単な方法が見つからなかったため、新しいサービスごとに、ApplicationRunnerにウォームアップコールを追加する必要があります。

SpringBootアプリケーションのクラスを自動的にロードするか、そのすべてのルートをウォームアップするソリューションは誰にもありますか?


詳細を追加できますか?アプリケーションはコントローラーをインスタンス化していますか?または、他のサービスを呼び出していますか?他のサービスをどのように呼び出していますか?
メニオス

Spring Bootはクラススキャンを集中的に使用するため、デスクトップアプリケーションのようなものを「ウォームアップ」する必要はありません。この長い初期ロードは、リソース検索(ページテンプレートのロードなど)の結果である可能性があります。
Alex Chernyshev

少し間接的なアプローチ:エンドポイントの100%の単体テストカバレッジがある場合、それらを使用できます。あなたはまだエンドポイントごとにコードを持っているだろうが、あなたが何か得る
Marged

1
実行しているプロジェクトによっては理想的ではない可能性がありますが、アプリケーションが読み込まれるときにエンドポイントを内部的に呼び出すことができます。
omoshiroiii

@omoshiroiii 何も問題はありません。私達はできる。生産中。その理由は、使用するいくつかの動的ライブラリと関係がinvokedynamicあり、それらの最初の呼び出しでは解決が遅いことがわかっています(このような呼び出しは数万あり、この最初の呼び出しがないと数十秒に蓄積されます)。
ユージーン

回答:


1

Javaのクラスローディングは遅延です。これは、クラスが必要な場合、必要な場合にのみ、JVMによってクラスがロードされることを意味します。

強制的にクラスをロードしたい場合は、それらを参照するだけで済みます。これを行う1つの方法は、jarコンテンツまたはクラスファイルを反復処理してクラス名を取得し、それらを使用してを呼び出すことClass.forName(className)です。

さらに、起動時間とパフォーマンスがユースケースにとって非常に重要である場合は、GraalVMなどのコンパイルソリューションを事前に調査するか、JITのコンパイルしきい値を下げることができ-XX:CompileThresholdます()。


それらのどちらもOPの問題を解決しません。読み込みはGraalVMではまだ遅延してJITおり、最初の呼び出しでは実際には意味がありません。
ユージーン

また、GraalVM良いですが、githubにある問題の数を確認してください。サンドボックスプロジェクトからより大きなもの(主にリフレクションを調べています)に移動するとすぐに、少し苦痛になります。少なくとも。私の要点は、GraalVMへのスワッピングは単純な指のスナップではありません。
ユージーン

jarにクラスをロードすることを考えましたが、それを行う方法が見つかりませんでした。例はありますか?
Ybri

@Eugene私の答えを読むと、GralVMを言っていなかったり、JITのしきい値によってクラスの読み込みの遅延が変わったりすることがわかります。怠惰に関するOPの質問に対する答えは、その前の段落です。最後の段落は、OPがクラスのロードを超えて起動時間/パフォーマンスをさらに最適化する必要がある場合の追加のヒントにすぎません。
andresp

1
@Ybri他にも質問があります。たとえば、stackoverflow.com
questions / 2370867 /…

0

私にとって、唯一可能な実行可能なオプションはclass data sharingJEP 310JEP 341JEP 350に広がっていますが、これにはおそらくJava-13が必要です。私たちはこれを私の職場で内部的にテストしています(ほとんどの場合、うそをつくことはありません)。結果は今のところ良好です。

もう1つのオプションは、アプリケーションの起動時にエンドポイントを呼び出すことです(オプションの場合)。繰り返しになります、たとえば、コードをウォームアップするために、ダミーデータで数百回呼び出します。しかし、同時に、これが不可能なサービスも提供しています。そのため、探索も行いCDSます。


運用データベースでのデータの作成を回避するために、認証とポストエンドポイントをどのように処理しますか?
Ybri

@Ybri正確に私が言った理由、いくつかは不可能
ユージーン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.