Java パフォーマンスの決定版ガイド - 概要 4

Java パフォーマンス チューニング ツールボックス

オペレーティング システム ツールと分析

CPU実行キュー

簡単な概要

  1. アプリケーションのパフォーマンスをチェックするとき、最初に確認する必要があるのは CPU 時間です。
  2. コードを最適化する目的は、CPU 使用率を (短期間に) 削減するのではなく、増加させることです。
  3. アプリケーションを徹底的に最適化する前に、まず CPU 使用率が低い理由を理解する必要があります。

ディスクの使用状況

ディスク使用量の監視には 2 つの目的があります。最初の目的はアプリケーション自体に関係します。アプリケーションが大量のディスク I/O を実行している場合、I/O は簡単にボトルネックになる可能性があります。

ディスク I/O がいつボトルネックになるかを知ることは、アプリケーションの動作に依存するため困難です。アプリケーションがディスクにデータを書き込むときに効果的にバッファリングを行わないと、ディスク I/O 統計が非常に低くなります。ただし、アプリケーションがディスクの処理能力を超える I/O を実行すると、ディスク I/O 統計は非常に高くなります。どちらの場合もパフォーマンスを改善する必要があります。
一部のシステムは、他のシステムよりも優れた基本的な I/O モニタリングを備えています。これは、Linux システム上の iostat の出力の一部です。
ここに画像の説明を挿入
アプリケーションはデータをディスク sda に書き込んでいます。一見したところ、ディスク統計は悪くありません。w_await (各 I/O の書き込み時間) は非常に短く (6.08 ミリ秒)、ディスク使用率はわずか 1.04% です。(許容可能な値は物理ディスクによって異なりますが、15 ミリ秒未満です。) しかし、ここに何か問題があることを示すヒントがあります。システムは時間の 37.89% をカーネルで費やしています。可能性の 1 つは、システムが (他のプログラムで) 他の I/O を実行していることです。このシステム時間がテスト対象のアプリケーションから取得されている場合は、何か非効率なことが起こっています。

もう 1 つの手がかりは、システムが 1 秒あたり 24.2 の速度で書き込みを行っているということです。1 秒あたりわずか 0.14 MB の書き込みでは、これは多量です。これは、I/O がすでにボトルネックになっていることを示しており、次のステップはアプリケーションの記述方法を確認することです。

ディスク速度が I/O リクエストに追いつけない場合、問題の裏側が現れます。Linux には、
ここに画像の説明を挿入
ディスク使用率が 100% であることをすぐに知らせるという利点があります。また、プロセスのイベントの 47.89% が進行中iowait(ディスクを待っていることを意味します) であることもわかります。

アプリケーションの I/O が高くなると予想されない場合でも、ディスク使用量を監視する 2 番目の理由は、システムがメモリをスワップしているかどうかを監視するためです。コンピューターの物理メモリの量は固定されていますが、より大きな仮想メモリを使用してさまざまなアプリケーションを実行できます。アプリは実際に必要なメモリよりも多くのメモリを予約し、多くの場合、アプリに割り当てられたメモリの一部しか使用しません。どちらの場合も、オペレーティング システムは未使用のメモリをディスク上に保持し、必要に応じて物理メモリにページングできます。

ほとんどの場合、このタイプのメモリ管理は、特に対話型アプリケーションや GUI プログラムでうまく機能します。このタイプの管理は、より多くのメモリを必要とするサーバー タイプのアプリケーションではあまり効果的ではありません。Java ヒープがあるため、この管理は Java プログラムにとって好ましくありません。

メモリをスワップしている (メイン メモリからディスクに、またはその逆にデータを移動している) システムは、一般にパフォーマンスが低下します。システム スワップをレポートできるシステム ツールは他にもあります。たとえば、vmstat 出力にはシステムがスワップしている場合に警告できる 2 つの列 (si はスワップ イン、つまりスワップ アウト) があります。ディスク アクティビティは、メモリ スワップが行われている可能性があることを示しています。
簡単な概要

  1. ディスク使用量の監視は、すべてのアプリケーションにとって重要です。ディスクに直接書き込まないアプリケーションであっても、システムのスワップがパフォーマンスに影響を与える可能性があります。
  2. ディスクに書き込むアプリケーションは、データが効率的に書き込まれていない (スループットが低すぎる)、または書き込まれるデータが多すぎる (スループットが高すぎる) ためにボトルネックに遭遇します。

ネットワークの使用状況

Java EE アプリケーション サーバーなど、アプリケーションの実行にネットワークが必要な場合は、ネットワーク トラフィックも監視する必要があります。ネットワーク使用量はディスク トラフィックと似ています。アプリケーションがネットワークを十分に活用していないために帯域幅が低くなっているか、ネットワーク インターフェイスに書き込まれるデータの総量が処理できる量を超えている可能性があります。

標準的なシステム ツールは、通常、ネットワーク インターフェイスで送受信されたデータグラムとバイト数しか表示できないため、ネットワーク トラフィックの監視には不向きです。この情報は役に立ちますが、ネットワークが十分に活用されていないのか、それとも過剰に活用されているのかを知ることはできません。Unix システムがネットワークを監視するための基本ツールは netstat です。これは、ネットワーク インターフェイスの使用状況を含む、各ネットワーク インターフェイスのトラフィックの概要を表示できます。この例の e1000g1 は 1000 MB インターフェイスで、使用率は非常に低いです
ここに画像の説明を挿入
( 0.33%)。このツール (および同様のツール) は、インターフェイスの使用量を計算するために使用できます。上記の出力では、インターフェイスのデータ書き込み速度は 225.7 Kbps、読み取り速度は 176.2 Kbps です。1000MB ネットワークの場合、分割後の使用率は 0.33% になる可能性があり、nicstat はインターフェイスの帯域幅を自動的に計算することもできます。

typeperf や netstat などのツールは、読み書きされたデータをレポートできますが、ネットワーク使用量を計算するには、インターフェイスの帯域幅を自分でスクリプト化する必要があります。一般的なツールで報告される単位はバイト/秒 (Bps) ですが、帯域幅の単位はビット/秒 (bps) です。1000 メガビットのネットワークは、1 秒あたり 125 メガバイト (MB) を処理します。この例では、読み取りは 0.22 MBps、書き込みは 0.16 MBps、加算して 125 で割ると、0.33% の使用率が得られます。nicstat の方が使いやすいです。

ネットワークは 100% の使用率をサポートできません。ローカル イーサネット LAN の場合、ネットワーク使用率が 40% を超える状態が続くと、インターフェイスが飽和していることを意味します。ネットワークがパケット交換されている場合、または別の伝送媒体を使用している場合、ネットワーク使用率の最大値は異なる可能性があるため、適切な値を決定する前にネットワーク アーキテクチャを評価することが最善です。この値は Java とは関係なく、単にネットワーク パラメーターとオペレーティング システム インターフェイスを使用します。

簡単な概要

  1. ネットワークベースのアプリケーションの場合、ネットワークを監視してボトルネックになっていないことを確認することが重要です。
  2. 往网络写数据的应用遇到瓶颈,可能是因为写数据的效率太低(吞吐量太低),也可能是因为写入了太多的数据(吞吐量太高)。
    

Java監視ツール

JVM 自体についての洞察を得るには、Java 監視ツールを使用する必要があります。JDK には以下のツールが付属しています。

  • jcnd

Java プロセスに関係する基本的なクラス、スレッド、および VM 情報を出力するために使用されます。これはスクリプトで動作し、次のように実行できます。

%jcmd process_id conmand optional_arguments

jcmd helpすべてのコマンドをリストできます。jcmd help <command>特定のコマンドの構文を指定できます。

  • jコンソール

スレッドの使用状況、クラスの使用状況、GC アクティビティなどの JVM アクティビティをグラフィカルに表示します。

  • ジャット

メモリ ヒープ ダンプを読み取り、分析に役立ちます。それは後付けの考えです。

  • jmap

ヒープ ダンプおよび JVM メモリ使用量に関するその他の情報を提供します。スクリプトに適用できますが、ヒープ ダンプは事後分析ツールで使用する必要があります。

  • ジンフォ

JVM のシステム プロパティを表示すると、一部のシステム プロパティを動的に設定できます。スクリプトで使用できます。

  • jスタック

Javaプロセスのスタック情報をダンプします。スクリプトで使用できます。

  • 立つ

GC およびクラス読み込みアクティビティに関する情報を提供します。スクリプトで使用できます。

  • jvisualvm

JVM を監視する GUI ツール。実行中のアプリケーションの分析や JVM ヒープ ダンプの分析に使用できます (イベント後、jvisualvm はプログラム ヒープ ダンプをリアルタイムで取得することもできます)。

これらのツールは、次の分野で広く使用されています。

  • VM の基本情報
  • スレッド情報
  • クラス情報
  • リアルタイム GC 分析
  • ヒープダンプの事後処理
  • JVMのパフォーマンス分析

ツールと応用分野の間には 1 対 1 の対応関係はなく、多くのツールは複数の分野で使用できます。したがって、各ツールを個別に調べる代わりに、Java の重要な観察可能な領域に注目し、これらのツールがこの情報をどのように提供するかについて説明します。同時に、同じ基本機能を提供するものの、基本的な JDK ツールよりも優れた利点がある他のツール (オープン ソース、商用) についても説明します。

VM の基本情報

JVM ツールは、JVM プロセスの基本的な実行情報 (実行時間、使用されている JVM フラグ、JVM システム プロパティなど) を提供できます。
実行時間
このコマンドは、JVM の実行時間を表示できます。

% jcmd process_id VM.uptime

システム プロパティ
次のコマンドで表示できるSystem.getProperties()個別のエントリ。

% jcmd process_id VM.systen_properties

また

% jinfo -sysprops process_id

これには、コマンド ラインの -D フラグで設定されたすべてのプロパティ、アプリケーションによって動的に追加されたすべてのプロパティ、および JVM のデフォルト プロパティが含まれます。

JVM バージョン
JVM バージョンは次の方法で取得します。

% jcmd process_id VM.version

JVM コマンド ライン
jconsole の「VM 概要」ページでは、プログラムで使用されるコマンド ラインを表示したり、jcmd を使用して表示したりできます。% jcmd process_id VM.command_line

JVM チューニング フラグ
アプリケーションに有効な JVM チューニング フラグは、次の方法で取得できます。

% jcmd process_id VM.flags [-all]

チューニング フラグ
JVM は多くのチューニング フラグを設定できます。上記の最後の 2 つの jcmd 例は、この種の情報を取得するのに役立ちます。command_line は、コマンド ラインで直接指定されたフラグを表示します。flags には、コマンドラインによって設定されたフラグと、JVM によって直接設定されたフラグが表示されます (値は自動最適化によって決定されるため)。このコマンドに all を追加すると、JVM 内のすべてのフラグをリストできます。

パフォーマンスの問題を診断するときは、どのフラグが有効であるかを確認するのが一般的です。JVM の実行中に、jcmd を使用してこれを行うことができます。-XX:+Printflagsfinal特定の JVM のプラットフォーム固有のデフォルトを調べたい場合は、コマンド ラインで追加すると便利です。
特定のプラットフォームにどのようなフラグが設定されているかを確認するには、次のコマンドを実行します。
% java other_options -XX:+PrintFlagsFinal -version
...以下を含む数百行の出力

uintx InitialHeapSize : = 4169431040  {product}
intx InlineSmallCode   = 2000                {pd product}

一部のフラグは他のフラグ、特に GC 関連のフラグに影響を与えるため、すべてのフラグをコマンド ラインに含める必要があります。このコマンドは、JVM フラグとその値の完全なリストを出力します (結果は、VM.flags -all と組み合わせた jcnd によって出力されるものと同じです)。これらのコマンドのフラグ データは、上記の 2 つの方法のいずれかで表示されます。出力の 1 行目のコロンは、フラグがデフォルト以外の値を使用していることを示します。この状況は次の理由によって発生する可能性があります。

  • フラグ値はコマンドラインで直接指定します。
  • 他のフラグは、このフラグの値を間接的に変更します。
  • JVM は、計算されたデフォルト値を自動的に最適化します。

行 2 (コロンなし) は、値がこの JVM バージョンのデフォルトであることを示します。出力の右端の列に示されているように、一部のフラグのデフォルト値はプラットフォームによって異なる場合があります。product は、デフォルト設定がすべてのプラットフォームで同じであることを意味します。pd 製品表現フラグのデフォルト値はプラットフォームに依存しません。

実行中のアプリケーションに関するこのような情報を表示するためのもう 1 つのツールは jinfo と呼ばれます。jinfo の優れた点は、プログラムの実行中にフラグの値を変更できることです。
プロセス内のすべてのフラグの値を取得する方法は次のとおりです:
% jinfo -flags process_id

jinfo に -flags がある場合は、すべてのフラグに関する情報を提供できます。それ以外の場合は、コマンド ラインで指定されたフラグのみを出力します。どちらの
データも -XX:+Printflagsfinal ほど読みやすくはありませんが、jinfo には他にも注目すべき機能があります。

jinfo は個々のフラグの値を確認できます。

% jinfo -flag PrintGCDetails process_id
-XX:+PrintGCDetails

jinfo 自体は管理可能かどうかを示しませんが、管理可能 (Printflagsfinal 出力で識別される) フラグは jinfo によってオンまたはオフにできます。

% jinfo -flag -PrintGCDetails process_id # turns off PrintGCDetails
% jinfo -flag PrintGCDetails process_id
-XX:-PrintGCDetails

jinfo は任意のフラグの値を変更できますが、それは JVM が変更に応答することを意味するわけではないことに注意してください。たとえば、GC アルゴリズムの動作に影響を与えるフラグのほとんどは、ガベージ コレクターの動作を決定するために起動時に使用されます。後で jinfo 経由でフラグ値を変更しても、JVM の動作は変わりません。元のアルゴリズムが継続されます。したがって、この手法は、Printflagsfinal 出力で管理可能としてマークされたフラグに対してのみ機能します。

簡単な概要

  1. jcmd を使用すると、すべてのチューニング フラグの値を含む、アプリケーションを実行している JVM に関する基本情報を見つけることができます。
  2. 2. コマンドラインに l を追加して-XX:+Printflagsfina、フラグのデフォルト値を出力します。これは、プラットフォーム固有の自動最適化によって決定されるデフォルト値を確認するときに役立ちます。
    3. info は、個々のフラグを検査する (場合によっては変更する) 場合に便利です。

おすすめ

転載: blog.csdn.net/weixin_42583701/article/details/130998187