プロファイリングの概要
プロファイリングは、大量のランタイムデータを扱ってプロセス内部の全体像を把握できる、実行時解析の一種です。 収集したデータは、CPU使用率、メモリの割り当て、ゴルーチンの活動状況など、プログラムの動作に関するさまざまな側面に関連しています。
プロファイリングは、メモリスナップショットの取得のような瞬時のものや、長時間にわたるものがあります。
プロファイリングが役立つのはいつですか?
プロファイリングツールは次のことに役立ちます。
ボトルネックを特定し、パフォーマンス低下の原因を診断する
ホットスポットや最適化の機会を特定し、パフォーマンス問題に直接関連しない場合もあります
プログラム内部の動作をより深く理解する
利用可能なプロファイル
GoLand は runtime/pprof パッケージの組み込みプロファイルを使用します。 各プロファイルは特定の種類のパフォーマンスデータを収集します。

CPU プロファイル
CPU プロファイルはプログラムがどこで CPU 時間を消費しているかを示します。
Go プロファイラーで作成したプロファイリングスナップショットは、さまざまなサンプルタイプで表示できます。
CPU 時間 は、CPU が関数を実行するのに要した時間を示します。 この値はサンプリングデータから派生し、推定実行時間を表します。 このサンプルタイプを使って、CPU 負荷の高いコードパスを特定し、アルゴリズムを最適化できます。
サンプル は、収集されたサンプル内で関数が出現した回数を示します。 プロファイラーは定期的にコールスタックを取得し、各取得がサンプルとなります。 サンプル数が多いほど、実行中にその関数が頻繁に観測されたことを意味します。 このサンプルタイプを利用して、ホットスポットを素早く検出できます。
このプロファイラーは、I/O や同期待ちではなく、実際に処理を行う関数を特定するのに役立ちます。
ヒーププロファイルおよびアロケーションプロファイル
ヒープ および Allocs プロファイルは、ランタイムによって収集されたメモリの割り当てデータを報告します。
両方のプロファイルは同じ割り当てイベントを使用します。 違いは、デフォルトのサンプルタイプです:
ヒープ は
in-use spaceを使用し、プログラムが現在利用しているメモリを表示します。Allocs は
allocated spaceを使用し、すでに解放されたメモリを含む、これまでに割り当てられたメモリの合計を表示します。
これらのプロファイルを使ってメモリ使用量を分析し、頻繁に割り当てを行うコードを特定します。 詳細については、 ヒーププロファイルおよび アロケーションプロファイルを参照してください。
GoLand ではヒーププロファイルを収集する方法がある:
GC 対象のヒープ領域 は、プロファイルを収集する前にガベージコレクションを実行します。 このオプションを利用すると、クリーンアップ後にまだ保持されているメモリを分析できます。
GC 対象外のヒープ領域 は、最初にガベージコレクションを強制せずにプロファイルを収集します。 このオプションを利用すると、追加のクリーンアップを行わずに現在のメモリの状態を確認できます。
ヒープ および Allocs プロファイルで利用可能なサンプルタイプは次の通りです:
割り当て済みオブジェクト (
alloc_objects):割り当てられたオブジェクトの数。割り当て済み領域 (
alloc_space):割り当てられたメモリの合計。使用中のオブジェクト (
inuse_objects):現在メモリ上に存在するオブジェクトの数。使用中の領域 (
inuse_space):現在使用中のメモリ。
ゴルーチンプロファイル
ゴルーチン プロファイルは、現在のすべてのゴルーチンのスタックトレースを表示します。
ゴルーチンは Go ランタイムが管理する軽量スレッドです。 このプロファイルを使って並行性を理解し、停止または想定外のゴルーチンを検出します。
ゴルーチンリークプロファイル
ゴルーチンリーク プロファイルは、Go ランタイムが決して実行を再開できないと判定したゴルーチンを表示します。たとえば、他のゴルーチンが到達できないチャネルやロックでブロックされている場合です。
ゴルーチン プロファイルが取得時点で存在するすべてのゴルーチンを一覧するのとは異なり、 ゴルーチンリーク プロファイルはガベージコレクタが到達不能かつ永久にブロックされていると判断したゴルーチンのみを報告します。 これは、アイドル状態であっても再開可能なゴルーチンによる誤検知を防ぎます。
このプロファイルを使ってゴルーチンリーク、つまり時間の経過とともに蓄積されてクリーンアップされず、徐々にメモリやその他のリソースを消費するゴルーチンを特定します。
ブロックプロファイル
ブロック プロファイルはゴルーチンが同期プリミティブで待機している場所を示します。
同期プリミティブは、ゴルーチン間で作業を調整し、共有データへのアクセスを管理するための仕組みです。 Go での一般的な例には、チャネル、 sync.Mutex、 sync.RWMutex、 sync.WaitGroup、 sync.Cond などがあります。
これは、チャネル送信・受信、ロック、その他の同期操作でブロックされていた経過時間を記録します。
このプロファイルを使うことで、同期やゴルーチン間の待機による遅延を特定できます。
以下のサンプルタイプが利用可能です:
遅延 :ゴルーチンが同期プリミティブの待機でブロックされていた累積時間。
争い :同期待機イベントの回数。
詳細については、 ブロックプロファイルを参照してください。
ミューテックスプロファイル
Mutex プロファイルはロック競合を表示します。
ミューテックスは共有データを保護するためのロックです。 複数のゴルーチンが同時に同じロックを獲得しようとすると、競合が発生します。 ゴルーチンがロックをすでに保持している場合、他のゴルーチンはロックが解放されるまで待つ必要があります。
このプロファイルを使って、ロック競合や過剰な同期による遅延を特定します。
以下のサンプルタイプが利用可能です:
遅延 :ゴルーチンが競合ロックの獲得を待っていた累積時間。
争い :ロック取得時に競合が発生した回数。
詳細については、 ミューテックスプロファイルを参照してください。
Go プロファイラーの構成
Go プロファイラーの設定は IDE 設定で行います。 設定は、プロファイルの保存先とプロファイラーがデータを収集する頻度を定義します。
アプリケーションのプロファイリング設定
Ctrl+Alt+S を押して設定を開き、 に移動します。
グローバルなプロファイリングパラメーターを構成します:
デフォルトのプロファイリングディレクトリ は、IDE がキャプチャしたプロファイルの保存先を定義します。
メモリプロファイリングレート は、プロファイラーがメモリの割り当てをサンプリングする頻度を定義します。
値は、記録された割り当て間の平均バイト数を示します。 値を下げると詳細度とオーバーヘッドが増加します。 デフォルト値は 512 KB です。
ブロックプロファイリングレート は、プロファイラーがブロッキングイベントを記録する頻度を定義します。
値はナノ秒単位で測定されます。 より多くのイベントを記録するには、値を小さく設定します。
ミューテックスプロファイリング割合 は、プロファイラーが記録するミューテックス競合イベントの件数を定義します。
値はサンプリング比率を制御します。 例えば、値 10 はプロファイラーが 10 件中 1 件のイベントを記録することを意味します。
テストのプロファイリング設定
Ctrl+Alt+S を押して設定を開き、 に移動します。
テスト実行用のプロファイラーを構成します:
CPU プロファイラー はテスト実行中の CPU 使用率を記録します。
メモリプロファイラ はメモリの割り当てを記録します。
プロファイリングレート を使って、プロファイラーが割り当てをサンプリングする頻度を定義します。 すべての割り当てを記録するには、値を
1に設定してください。 デフォルト値(512 KB)を使用するには、フィールドを空白のままにします。ブロッキングプロファイラー はブロッキングイベントを記録します。
ブロックイベントは、ゴルーチンがチャネルやロックなどのリソースを待機する際に発生します。
プロファイリングレート を使い、プロファイラーがブロッキングイベントをサンプリングする頻度を定義します。 すべてのイベントを記録するには、値を
1に設定してください。ミューテックスプロファイラー はミューテックス競合を記録します。
ミューテックス競合は、複数のゴルーチンが同じロックを取得しようとしたときに発生します。
プロファイリング割合 を使用して、プロファイラーがどの割合でイベントを記録するかを定義します。 例えば、値 10 はプロファイラーが 10 件中 1 件のイベントを記録することを意味します。
プロファイリングの仕組み
GoLand は標準の Go pprof ツールを使ってプロファイリングデータを収集します。
プロファイリングを開始すると、IDE はアプリケーションを一時的なオーバーレイでビルドします。 オーバーレイはソースファイルを変更せずに、ビルドにプロファイリングフックを注入します。
IDE は次のようなコマンドを実行します:
オーバーレイファイルはプロファイリングを有効化する一時的な変更を定義します。 GoLand は実行完了後にこれらの変更を削除します。