エスケープ解析分析
エスケープ解析は、Go コンパイラーが値をスタックではなくヒープに配置する理由を理解するのに役立ちます。 ヒープ割り当てはメモリ使用量を増やし、ガベージコレクターの負担を増やす可能性があります。
GoLand は go build -gcflags="-m" コマンドを使ってエスケープ解析を実行します。 GoLand はコマンドの出力を処理し、その結果をコードに反映します。 これにより、コンパイラーメッセージへの移動、エスケープフローの確認、エディターで最適化の判断を理解することができます。
エスケープ解析を実行する
ファイルやパッケージごとにエスケープ解析を実行できます。
ファイルまたはパッケージのエスケープ解析を実行する
メインメニューから を選択します。
Go のパフォーマンス最適化 ツールウィンドウで、 エスケープ解析分析 を選択します。
スコープを選択してください:
ファイル: 選択したファイルを解析します。
パッケージを実行: 選択したパッケージを解析します。
表示したいエスケープ解析メッセージを選択します。
(オプション)Go プロセスの環境変数を指定します。
エスケープ解析の実行 をクリックしてください。

エディターで結果を表示する
解析が完了すると、GoLand はエディターのガターにエスケープ解析メッセージを表示します。
複数のメッセージが同じ行に属する場合、ガターマーカーはこの行のログ数を表示します。例えば、 2 件のログ。

ガターメッセージを確認する
ガターマーカーにカーソルを合わせます。
ポップアップでコンパイラーメッセージとエスケープフローを確認します。

関数名にカーソルを合わせると、その関数のエスケープ解析結果を表示できます。
結果からコードへ移動する
GoLand は Go のパフォーマンス最適化 ツールウィンドウにもエスケープ解析結果を表示します。
ツールウィンドウ内の結果をクリックすると、エディターの該当行へ移動します。
コード内の結果へ移動する
メインメニューから を選択します。
Go のパフォーマンス最適化 ツールウィンドウで、キャッチしたいイベントを選択し、 エスケープ解析の実行 をクリックします。
結果タブでファイル、関数、またはメッセージカテゴリを展開します。
結果をクリックします。
GoLand はエディターの該当行にキャレットを移動します。
結果をフィルターおよびグループ化する
エディターおよびツールウィンドウでエスケープ解析メッセージをフィルターできます。
エスケープ解析メッセージをフィルターする
エスケープ解析を実行した後 、結果タブで ログをフィルタリングする をクリックします。
表示したいメッセージタイプを選択します。
結果ビューを変更する
View をクリックしてください。
ビューのいずれかを選択してください:
ツリー: ファイル、関数、メッセージタイプごとにグループ化された結果を表示します。

コンソール出力:
go build -gcflags="-m"コマンドの出力を表示します。 このビュー内の結果をクリックすると、該当行へ移動できます。
結果をグループ化する
グループ化 をクリックしてください。
GoLand で結果をどのようにグループ化するかを選択してください(例:関数単位やカテゴリ単位)。
一般的なエスケープ解析メッセージを理解する
エスケープ解析は、値がスタックに割り当てられるか、ヒープに割り当てられる必要があるかを判定します。
多くのヒープ割り当ては必要であり、パフォーマンス上の問題ではありません。 エスケープ解析はベンチマークやプロファイリング結果と組み合わせて使い、パフォーマンスに影響する割り当てを特定してください。
メッセージタイプ | 説明 |
|---|---|
ヒープへのエスケープ | 値が現在の関数の戻り値で必要となるためヒープに割り当てるべきであることを示します。
func create() *int {
x := 10
return &x
}
この例では、関数が |
ヒープへ移動済み | 関数の戻り後に値が不要になると保証できないため、コンパイラーが値をヒープに割り当てたことを示します。
func process() {
value := 42
use(&value)
}
この例では、 |
パラメーターのリーク | 関数パラメーターが関数から逃げ、関数の戻り後も有効である必要があることを示します。
func store(p *int) *int {
return p
}
この例では、関数がパラメーター |
インライン化可能 | 関数が十分に小さく単純なため、コンパイラーが関数呼び出しを関数本体で置き換えられることを示します。
func add(a, b int) int {
return a + b
}
この例では、関数はシンプルな処理を含み、小さな本体を持っています。 コンパイラーは関数呼び出しのオーバーヘッドを減らし、最適化の機会を増やすために関数をインライン化できます。 |
呼び出しのインライン化 | コンパイラーが関数呼び出しをコンパイル時に関数本体で置換したことを示します。
func add(a, b int) int {
return a + b
}
func main() {
_ = add(1, 2)
}
この例では、コンパイラーが インライン化可能 は関数がインライン化の対象であることを示します。 呼び出しのインライン化 はコンパイラーが特定の関数呼び出しを実際にインライン化したことを示します。 |
その他 | エスケープ解析や最適化の判断に関連する追加のコンパイラー診断を表示します。 |