Documentation
¶
Overview ¶
pprofパッケージは、pprof視覚化ツールで期待される形式でランタイムプロファイリングデータを書き込みます。
Goプログラムのプロファイリング ¶
Goプログラムをプロファイリングする最初のステップは、プロファイリングを有効にすることです。 標準のテストパッケージでビルドされたベンチマークのプロファイリングをサポートするためには、go testに組み込まれています。 たとえば、次のコマンドは現在のディレクトリでベンチマークを実行し、CPUプロファイルとメモリプロファイルをcpu.profとmem.profに書き込みます:
go test -cpuprofile cpu.prof -memprofile mem.prof -bench .
スタンドアロンのプログラムに同等のプロファイリングサポートを追加するには、以下のようなコードをmain関数に追加します:
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
defer f.Close() // エラーハンドリングは例外です
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}
// ... プログラムの残り ...
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
defer f.Close() // エラーハンドリングは例のため省略
runtime.GC() // 最新の統計情報を取得
// Lookup("allocs")は go test -memprofile と同様のプロファイルを作成します。
// または、Lookup("heap")を使うことで、
// デフォルトのインデックスが inuse_space となるプロファイルを取得できます。
if err := pprof.Lookup("allocs").WriteTo(f, 0); err != nil {
log.Fatal("could not write memory profile: ", err)
}
}
}
プロファイリングデータへの標準のHTTPインターフェースもあります。以下の行を追加すると、/debug/pprof/の下にハンドラがインストールされ、ライブプロファイルをダウンロードすることができます:
import _ "net/http/pprof"
詳細については、net/http/pprofパッケージを参照してください。 プロファイルはpprofツールで可視化することができます:
go tool pprof cpu.prof
pprofコマンドラインからは多くのコマンドが利用できます。 よく使用されるコマンドには、「top」(プログラムのホットスポットの要約を表示する)や、「web」(ホットスポットとその呼び出しグラフの対話型グラフを開く)があります。 すべてのpprofコマンドに関する情報については、「help」を使用してください。 pprofに関する詳細情報は、次を参照してください
Index ¶
- func Do(ctx context.Context, labels LabelSet, f func(context.Context))
- func ForLabels(ctx context.Context, f func(key, value string) bool)
- func Label(ctx context.Context, key string) (string, bool)
- func SetGoroutineLabels(ctx context.Context)
- func StartCPUProfile(w io.Writer) error
- func StopCPUProfile()
- func WithLabels(ctx context.Context, labels LabelSet) context.Context
- func WriteHeapProfile(w io.Writer) error
- type LabelSet
- type Profile
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Do ¶ added in v1.9.0
親のコンテキストのコピーを使用して f を呼び出します。 親のラベルマップに指定されたラベルが追加されます。 f を実行する間に生成されたゴルーチンは、拡張されたラベルセットを継承します。 labels の各キー/値ペアは、提供された順序でラベルマップに挿入され、同じキーの以前の値を上書きします。 拡張されたラベルマップは、f の呼び出しの間、設定され、f の戻り値時に復元されます。
func ForLabels ¶ added in v1.9.0
ForLabelsはコンテキストに設定された各ラベルを持ってfを呼び出します。 関数fは繰り返しを続けるためにtrueを返すか、繰り返しを早期に停止するためにfalseを返す必要があります。
func SetGoroutineLabels ¶ added in v1.9.0
SetGoroutineLabelsは現在のゴルーチンのラベルをctxと一致させます。 新しいゴルーチンは、その作成元のゴルーチンのラベルを継承します。 これは、可能な場合は代わりに使用するべき Do よりも低レベルのAPIです。
func StartCPUProfile ¶
StartCPUProfileは現在のプロセスに対してCPUプロファイリングを有効にします。 プロファイリング中は、プロファイルがバッファリングされ、wに書き込まれます。 StartCPUProfileは、すでにプロファイリングが有効な場合にエラーを返します。
Unix系システムでは、-buildmode=c-archiveまたは-buildmode=c-sharedで ビルドされたGoコードでは、デフォルトではStartCPUProfileは動作しません。 StartCPUProfileはSIGPROFシグナルを利用していますが、 そのシグナルはGoが使用するものではなく、 メインプログラムのSIGPROFシグナルハンドラ(あれば)に送信されます。 関数 os/signal.Notify を syscall.SIGPROF に対して呼び出すことで、 それが動作するようにすることができますが、その場合、 メインプログラムで実行されているプロファイリングが壊れる可能性があります。
func StopCPUProfile ¶
func StopCPUProfile()
StopCPUProfileは現在のCPUプロファイルを停止します(もし存在する場合)。 StopCPUProfileはプロファイルの書き込みが完了するまでのみ戻ります。
func WithLabels ¶ added in v1.9.0
WithLabelsは指定されたラベルが追加された新しい context.Context を返します。 ラベルは同じキーを持つ以前のラベルを上書きします。
Types ¶
type LabelSet ¶ added in v1.9.0
type LabelSet struct {
// contains filtered or unexported fields
}
LabelSetはラベルのセットです。
type Profile ¶
type Profile struct {
// contains filtered or unexported fields
}
Profileは、特定のイベント(割り当てなど)のインスタンスに至る呼び出しシーケンスを 示すスタックトレースのコレクションです。 パッケージは独自のプロファイルを作成・維持することができます。最も一般的な 使用法は、ファイルやネットワーク接続など、明示的にクローズする必要がある リソースを追跡することです。
Profileのメソッドは複数のゴルーチンから同時に呼び出すことができます。
各Profileには一意の名前があります。いくつかのプロファイルが事前定義されています:
goroutine - 現在のすべてのゴルーチンのスタックトレース goroutineleak - リークしたすべてのゴルーチンのスタックトレース allocs - 過去のすべてのメモリ割り当てのサンプリング heap - ライブオブジェクトのメモリ割り当てのサンプリング threadcreate - 新しいOSスレッドの作成に至ったスタックトレース block - 同期プリミティブでのブロックに至ったスタックトレース mutex - 競合するミューテックスの保持者のスタックトレース
これらの事前定義されたプロファイルは自身を維持し、明示的な Profile.Add または Profile.Remove メソッド呼び出しでパニックを発生させます。
CPUプロファイルはProfileとしては利用できません。プロファイリング中に ライターに出力をストリーミングするため、特別なAPI、 StartCPUProfile と StopCPUProfile 関数があります。
Heap profile ¶
ヒーププロファイルは、最も最近に完了したガベージコレクション時点での 統計を報告します。ライブデータから離れてガベージに偏ることを避けるために、 より最近の割り当てを除外します。 ガベージコレクションがまったく行われていない場合、ヒーププロファイルは すべての既知の割り当てを報告します。この例外は主に、ガベージコレクション なしで実行されているプログラム(通常はデバッグ目的)で役立ちます。
ヒーププロファイルは、アプリケーションメモリ内のすべてのライブオブジェクトと、 プログラム開始以降に割り当てられたすべてのオブジェクトの両方の 割り当てサイトを追跡します。 Pprofの -inuse_space、-inuse_objects、-alloc_space、-alloc_objects フラグによってどれを表示するかを選択し、デフォルトは -inuse_space(ライブオブジェクト、 サイズでスケール)です。
Allocs profile ¶
allocsプロファイルはヒーププロファイルと同じですが、デフォルトのpprof表示を -alloc_space、つまりプログラム開始以降に割り当てられた総バイト数 (ガベージコレクションされたバイトを含む)に変更します。
Block profile ¶
ブロックプロファイルは、sync.Mutex、sync.RWMutex、sync.WaitGroup、 sync.Cond、およびチャネル送信/受信/selectなどの同期プリミティブで ブロックされた時間を追跡します。
スタックトレースは、ブロックした場所(例:sync.Mutex.Lock)に対応します。
サンプル値は、そのスタックトレースでブロックされた累積時間に対応し、 runtime.SetBlockProfileRate によって指定される時間ベースのサンプリングに 従います。
Mutex profile ¶
ミューテックスプロファイルは、sync.Mutex、sync.RWMutex、 およびランタイム内部ロックなどのミューテックスでの競合を追跡します。
スタックトレースは、競合を引き起こしたクリティカルセクションの終わりに対応します。 例えば、他のゴルーチンがロックの取得を待っている間に長時間保持されたロックは、 ロックが最終的に解放されたときに競合を報告します(つまり、sync.Mutex.Unlock で)。
サンプル値は、他のゴルーチンがロックを待ってブロックされた 概算の累積時間に対応し、runtime.SetMutexProfileFraction によって 指定されるイベントベースのサンプリングに従います。例えば、呼び出し元が 5つの他のゴルーチンが1秒全体でロックの取得を待っている間に1秒間ロックを 保持した場合、そのアンロック呼び出しスタックは5秒の競合を報告します。
func NewProfile ¶
NewProfileは指定された名前で新しいプロファイルを作成します。 すでにその名前のプロファイルが存在する場合、NewProfileはパニックを引き起こします。 各パッケージごとに別の名前空間を作成するために、'import/path.'接頭辞を使用するのが一般的です。 pprofデータを読み取るさまざまなツールとの互換性のために、プロファイル名にはスペースを含めないでください。
func (*Profile) Add ¶
Addは現在の実行スタックを、値と関連付けてプロファイルに追加します。 Addは値を内部のマップに保存するため、値はマップのキーとして使用するのに適しており、対応する Profile.Remove 呼び出しまでガベージコレクトされません。 Addはもしプロファイルにすでに値のスタックが含まれている場合、パニックを発生させます。
skipパラメータは runtime.Caller のskipと同じ意味を持ち、スタックトレースが始まる場所を制御します。 skip=0を渡すと、Addを呼び出した関数からトレースが始まります。例えば、以下のような実行スタックがあるとします:
Add rpc.NewClientから呼び出される mypkg.Runから呼び出される main.mainから呼び出される
skip=0を渡すと、スタックトレースはrpc.NewClient内でのAddの呼び出しで始まります。 skip=1を渡すと、スタックトレースはmypkg.Run内でのNewClientの呼び出しで始まります。
func (*Profile) WriteTo ¶
WriteToはプロファイルのスナップショットをwにpprof形式で書き込みます。 wへの書き込みがエラーを返す場合、WriteToはそのエラーを返します。 それ以外の場合、WriteToはnilを返します。
debugパラメータは追加の出力を有効にします。 debug=0を渡すと、https://github.com/google/pprof/tree/master/proto#overviewで 説明されているgzip圧縮されたプロトコルバッファ形式で書き込まれます。 debug=1を渡すと、関数名と行番号をアドレスに変換したレガシーテキスト形式で書き込まれます。 これにより、プログラマがツールなしでプロファイルを読むことができます。
プリセットのプロファイルは、他のdebugの値に意味を割り当てることができます。 たとえば、"goroutine"プロファイルの場合、debug=2は、 ゴルーチンのスタックをGoプログラムが回復不可能なパニックによって終了する際に使用する同じ形式で表示することを意味します。