web-dev-qa-db-ja.com

Java "ウォームアップ"時間を最小化するためのテクニックまたはユーティリティ?

Java低レイテンシを必要とするメッセージングアプリケーション(各メッセージの処理に300マイクロ秒未満)をサポートしています。ただし、プロファイリングでは、Sun Java仮想マシンが実行されていることを示しています。最初はゆっくりと、最初の5,000メッセージ以降はスピードアップします。最初の5,000メッセージは1〜4ミリ秒のレイテンシを持ちます。最初の5,000後、後続のメッセージは〜250マイクロ秒のレイテンシを持ち、時々異常値を示します。

これは、Javaアプリケーションの典型的な動作であると一般的に理解されています。ただし、ビジネスの観点から、JVMが「ウォームアップ」するまで待たなければならないことを顧客に伝えることは受け入れられません。最初の顧客メッセージが処理される前に、アプリケーションを「ウォームアップ」する必要があります

JVMはSun 1.6.0 update 4です。

この問題を克服するためのアイデア:

  1. -XX:CompileThreshold =などのJVM設定
  2. 起動時にアプリケーションを「ウォームアップ」するコンポーネントを追加します。たとえば、アプリケーションを介して「偽のメッセージ」を送信します。
  3. アプリケーションの起動時にアプリケーションとJDKクラスを静的にロードすることで、顧客メッセージの処理中にJARからクラスがロードされないようにします。
  4. 上記の2つのアイデアのいずれかまたは両方を実行するユーティリティまたはJavaエージェント。これにより、ホイールを再発明する必要がなくなります。

注:このソリューションでは、チップアーチ、ディスクの種類と構成、OSの設定など、すべての要素を調べています。ただし、この質問では、Javaアプリケーションを最適化し、「ウォームアップ」時間を最小限に抑えるために何ができるかについて焦点を当てたいと思います。

41
noahlz

Javaの「ウォームアップ」は一般に2つのことについてです:

(1):遅延クラスの読み込み:強制的に読み込むことで回避できます。

これを行う簡単な方法は、偽のメッセージを送信することです。偽のメッセージがクラスへのすべてのアクセスをトリガーすることを確認する必要があります。たとえば、空のメッセージを送信しても、プログラムがメッセージが空かどうかを確認し、特定の処理を行わない場合、これは機能しません。

これを行う別の方法は、プログラムの起動時にそのクラスにアクセスして、クラスの初期化を強制することです。

(2):リアルタイム最適化:実行時に、Java VMはコードの一部を最適化します。これがウォームがある主な理由ですアップタイム。

これを容易にするために、ユーザーが使用する前に最適化が完了するように、偽の(ただし、実際に見える)メッセージを送信できます。

これを容易にするために役立つもう1つの方法は、privateおよびfinalをできるだけ使用するなど、インラインをサポートすることです。その理由は、VMは継承テーブルを参照して、実際に呼び出されるメソッドを確認する必要がないためです。

お役に立てれば。

33
NawaMan

問題は、クラスの読み込みではなく、「ジャストインタイム」のコンパイルです。

-XX:CompileThreshold=1をお試しください

これにより、Javaは最初に実行するときにすべてをコンパイルします。コードの起動が多少遅くなりますが、VMコードではありません) Javaがインストールされている場合にコンパイルされます。)JavaがカスタムJARを同様の方法でコンパイルし、後で実行するために結果を保存することを許可するバグが開いています。このオーバーヘッドを大幅に削減しますが、このバグをすぐに修正する必要はありません。

2番目のオプションは、5,000の偽のメッセージをアプリに送信して「ウォームアップ」することです。 「すべてが正しく設定されていることを確認する」としてこれを売ります。

[編集]クラスのプリコンパイルの背景情報: クラスデータの共有

IBMのバージョンのJavaここから、共有プールにクラスを追加できるため、次のように試すことができます。 クラスデータ共有の概要

[EDIT2]kittylyst によって提起された懸念に答えるために、次のようなメソッドでコードキャッシュがすぐにいっぱいになることは事実です一度だけ使用されます。また、アプリ全体が遅くなる場合もあります。

低い値に設定すると、アプリケーションの起動時間がひどく遅くなる可能性があります。これは、JIT最適化+コンパイル済みコードの実行は、コードをインタープリターモードで1回実行するよりもコストがかかるためです。

ここでの主な問題は、コードがまだ「ジャストインタイム」でコンパイルされていることです。少なくとも1回は必要なすべてのメソッドを実行できない限り、アプリは、以前にコンパイルされていない何かに遭遇するたびに数ミリ秒間「起動」します。

しかし、RAMがある場合、アプリは小さいか、コードキャッシュのサイズを増やすことができ、起動時間が遅くてもかまわない場合は、これを試してみることができます。一般的に、デフォルト設定はかなり良いです。

15
Aaron Digulla

純粋な顧客トラフィック用に開かれる前に、システムを介して大量のノーオペレーションメッセージを実行するだけです。通常のメッセージは10kメッセージです。

金融アプリ(例:FIX)の場合、これは多くの場合、注文が(昨夜の終値から遠く離れた価格で)オープンする前に市場に送信することで行われます。それらはすべて拒否されますが、それは問題ではありません。

使用しているプロトコルが自作である場合、次にそのライブラリをアップグレードするときに、「WARMUP」、「TEST」、または「SANITYCHECK」メッセージタイプの明示的なサポートを追加します。

もちろん、これはアプリケーションロジック固有の経路をコンパイルしない可能性がありますが、まともなメッセージングアプリでは、ネットワークトラフィックを処理する部分がほぼ確実にスタックの主要部分になるため、問題ではありません。

7
kittylyst

最新のハードウェア(CPUあたり2コア以上)と最新バージョンのJDKでHotspotのサーバーモードで実行している場合、ウォームアップの高速化に次のオプションを使用できます。

-server -XX:+ TieredCompilation 
3

クライアントまたはサーバーJVMを使用していますか?プログラムを次のように開始してみてください:

Java -server com.mycompany.MyProgram

このモードでSunのJVMを実行すると、JITはバイトコードをネイティブコードにコンパイルします。このため、プログラムの起動には時間がかかりますが、その後はより速く実行されます。

参照: Java HotSpot VM)に関するよくある質問

見積もり:

-clientシステムと-serverシステムの違いは何ですか?

これら2つのシステムは異なるバイナリです。これらは基本的に、同じランタイムシステムに接続する2つの異なるコンパイラ(JIT)です。クライアントシステムは、起動時間が短いかフットプリントが小さいアプリケーションに最適です。サーバーシステムは、全体的なパフォーマンスが最も重要なアプリケーションに最適です。一般に、クライアントシステムはGUIなどの対話型アプリケーションに適しています。その他の違いには、コンパイルポリシー、ヒープのデフォルト、インラインポリシーなどがあります。

3
Jesper

古いスレッドですが、インターネットでこれを見つけました。

非常に興味深いのは、Sun HotSpot JVMに対するoption-XX:CompileThreshold = 1500の影響です。デフォルトはサーバーVMおよびクライアントVMの1500です。ただし、サーバーVMの場合は1500に設定すると、クライアントVMよりも高速になります。100に設定すると、実際にパフォーマンスを低下させ、option-Xcomp(つまり、すべてのコードが使用前にコンパイルされる)を使用すると、さらにパフォーマンスが低下します。これは驚くべきことです。

今、あなたは何をすべきかを知っています。

2
mark