5.2. パフォーマンスに関する問題の監視と診断

Red Hat Enterprise Linux 7 ではシステムのパフォーマンス監視やシステムメモリーに関連するパフォーマンスの問題の診断を行う際に便利なツールがいくつか用意されています。このセクションではこうしたツールを簡単に説明し、メモリー関連のパフォーマンス問題を監視、診断する方法を例を使って説明していきます。

5.2.1. vmstat を使ったメモリー使用量の監視

Vmstatprocps-ng パッケージで提供され、システムのプロセス、メモリー、ページング、入出力のブロック、割り込み、CPU アクティビティーに関する報告を出力します。最後にマシンを起動した時点または最後の報告を行った時点からのイベント平均を瞬時に報告します。
次のコマンドは各種イベントカウンターおよびメモリー統計の表を表示します。
$ vmstat -s
vmstat の使い方については 「vmstat」 または man ページを参照してください。
$ man vmstat

5.2.2. Valgrind を使ったアプリケーションのメモリー使用量のプロファイリング

Valgrind はユーザー領域のバイナリーに対するインストルメンテーションを提供するフレームワークになります。プログラムのパフォーマンスのプロファイリングや分析に使用できるツールがいくつか収納されています。このセクションで説明している valgrind ツールは、初期化されていないメモリーの使用、不適切なメモリー割り当て、割り当て解除などのメモリーに関するエラーの検出に役立ちます。
valgrind やそのツールを使用するには valgrind パッケージをインストールします。
# yum install valgrind

5.2.2.1. Memcheck を使ったメモリー使用量のプロファイリング

Memcheckvalgrind のデフォルトツールです。検出や診断が難しい次のようなメモリーエラーを検出、報告します。
  • 発生してはいけないメモリーアクセス
  • 未定義または未初期化の値の使用
  • ヒープメモリーの不正な解放
  • ポインターの重複
  • メモリーリーク

注記

Memcheck が行うのはエラーの報告だけでありその発生を防ぐことはできません。通常、セグメンテーション違反が発生するような形でプログラムによるメモリーアクセスが行われればセグメンテーション違反は発生します。ただし、memcheck により違反が発生する直前にエラーメッセージがログ記録されるようになります。
memcheck はインストルメンテーションを使用するため memcheck を付けて実行されるアプリケーションの実行速度は通常に比べ 10 倍から 30 倍ほど遅くなります。
アプリケーションで memcheck を実行するには次のコマンドを実行します。
# valgrind --tool=memcheck application
次のオプションを使用すると特定の問題タイプの memcheck 出力に集中させることもできます。
--leak-check
アプリケーションの実行が完了すると memcheck によりメモリーリークの検索が行われます。デフォルト値は検出したメモリーリーク数を出力する --leak-check=summary になります。--leak-check=yes--leak-check=full を指定するとリークそれぞれの詳細を出力させることができます。無効にする場合は --leak-check=no を指定します。
--undef-value-errors
デフォルト値は未定義の値が使用された場合にエラーを報告する --undef-value-errors=yes です。--undef-value-errors=no を指定するとこの報告を無効にしてメモリーチェックの速度を若干早めることができます。
--ignore-ranges
--ignore-ranges=0xPP-0xQQ,0xRR-0xSS などのようにメモリーアクセスを確認する際 memcheck に無視させる範囲を指定します。
memcheck オプションの全一覧は /usr/share/doc/valgrind-version/valgrind_manual.pdf に収納されているドキュメントをご覧ください。

5.2.2.2. Cachegrind を使ったキャッシュ使用量のプロファイリング

Cachegrind はシステムのキャッシュ階層および分岐予測を使ってアプリケーションのやりとりをシュミレーションします。シュミレーションされた第一レベルの指示とデータキャッシュの使用量を追跡し、このレベルのキャッシュで不良なアプリケーションコードのやりとりを検出します。また、メモリーへのアクセスを追跡するため最後のレベルのキャッシュ (第2 または第 3 レベル) も追跡します。このため、Cachegrind で実行されたアプリケーションは通常の実行に比べて 20 倍 から 100 倍の時間がかかります。
アプリケーション実行中の統計を収集しコンソールに要約を出力します。cachegrind をアプリケーションで実行する場合は次のコマンドを実行します。
# valgrind --tool=cachegrind application
cachegrind の出力を特定の問題に集中させる場合は次のオプションを使用することもできます。
--I1
--I1=size,associativity,line_size などのように第 1 レベルの命令キャッシュのサイズ、結合性、行サイズを指定します。
--D1
--D1=size,associativity,line_size などのように第 1 レベルのデータキャッシュのサイズ、結合性、行サイズを指定します。
--LL
--LL=size,associativity,line_size などのように最後のレベルのキャッシュのサイズ、結合性、行サイズを指定します。
--cache-sim
キャッシュアクセスおよびミスの数の収集を有効化または無効化します。デフォルトでは有効になっています (--cache-sim=yes)。このオプションと --branch-sim の両方を無効にすると cachegrind には収集する情報がなくなります。
--branch-sim
ブランチ命令と誤った予測数の収集を有効化または無効化します。デフォルトでは有効になっています (--branch-sim=yes)。このオプションと --cache-sim の両方を無効にすると cachegrind には収集する情報がなくなります。
Cachegrind はプロファイリングの詳細情報をプロセスごとの cachegrind.out.pid ファイルに書き込みます。pid はプロセスの識別子になります。この詳細情報は付随する cg_annotateツールでさらに以下のように処理することができます。
# cg_annotate cachegrind.out.pid
また、Cachegrind ではコード変更の前と後のプログラムパフォーマンスをより簡単に図表にすることができる cg_diff ツールも用意しています。出力ファイルを比較するには次のコマンドを実行します。first には初期プロファイルの出力ファイル、second には次のプロファイルの出力ファイルを入力します。
# cg_diff first second
結果の出力ファイルの詳細は cg_annotate ツールで表示させることができます。
cachegrind のオプション全一覧は /usr/share/doc/valgrind-version/valgrind_manual.pdf に収納されているドキュメントを参照してください。

5.2.2.3. Massif を使ったヒープとスタックの領域プロファイリング

Massif は指定アプリケーションが使用するヒープ領域を測定します。測定対象は、有用な領域および会計、調整用に割り当てられている追加領域の両方になります。massif はアプリケーションのメモリー使用を抑え実行速度を高めながらアプリケーションが swap 領域を使い切ってしまう可能性を低減する方法を理解する場合に役立ちます。massif を付けてアプリケーションを実行すると実行速度が通常より約 20 倍遅くなります。
アプリケーションで massif を実行するには次のコマンドを実行します。
# valgrind --tool=massif application
次のオプションを使用すると massif の出力を特定の問題に集中させることもできます。
--heap
massif にヒープのプロファイリングを行わせるかどうかを指定します。デフォルト値は --heap=yes です。--heap=no に設定するとヒープのプロファイリングが無効になります。
--heap-admin
ヒープのプロファイリングを有効にした場合の管理に使用するブロックごとのバイト数を指定します。デフォルト値は 8 バイトです。
--stacks
massif にスタックのプロファイリングを行わせるかどうかを指定します。スタックのプロファイリングにより massif の動作がかなり遅くなる可能性があるため、デフォルト値は --stack=no です。スタックのプロファイリングを有効にする場合は --stack=yes に設定します。プロファイリングするアプリケーションに関連するスタックサイズの変更をよりわかりやすく示すため massif はメインスタックの開始時のサイズはゼロであると仮定している点に注意してください。
--time-unit
massif でプロファイリングデータを収集する間隔を指定します。デフォルト値は i (命令を実行) です。ms (ミリ秒数またはリアルタイム) や B (ヒープおよびスタックで割り当てられたバイト数または割り当て解除されたバイト数) を指定することもできます。ハードウェアが異なる場合でもほぼ再現が可能なため短時間実行のアプリケーションやテスト目的の場合には割り当てられたバイト数を確認すると役に立ちます。
Massif はプロファイリングデータを massif.out.pid ファイルに出力します。pid は指定アプリケーションのプロセス識別子になります。ms_print ツールはこのプロファイリングデータを図式化しアプリケーション実行中のメモリー消費量を表示すると共にメモリー割り当てのピーク時に割り当てを行うサイトに関する詳細情報を表示します。massif.out.pid ファイルのデータを図式化するには次のコマンドを実行します。
# ms_print massif.out.pid
Massif のオプション全一覧は /usr/share/doc/valgrind-version/valgrind_manual.pdf に収納されているドキュメントを参照してください。