pprof

package
v1.26.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2026 License: MIT Imports: 4 Imported by: 0

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に関する詳細情報は、次を参照してください

https://github.com/google/pprof/blob/main/doc/README.md.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Do added in v1.9.0

func Do(ctx context.Context, labels LabelSet, f func(context.Context))

親のコンテキストのコピーを使用して f を呼び出します。 親のラベルマップに指定されたラベルが追加されます。 f を実行する間に生成されたゴルーチンは、拡張されたラベルセットを継承します。 labels の各キー/値ペアは、提供された順序でラベルマップに挿入され、同じキーの以前の値を上書きします。 拡張されたラベルマップは、f の呼び出しの間、設定され、f の戻り値時に復元されます。

func ForLabels added in v1.9.0

func ForLabels(ctx context.Context, f func(key, value string) bool)

ForLabelsはコンテキストに設定された各ラベルを持ってfを呼び出します。 関数fは繰り返しを続けるためにtrueを返すか、繰り返しを早期に停止するためにfalseを返す必要があります。

func Label added in v1.9.0

func Label(ctx context.Context, key string) (string, bool)

Labelは与えられたキーに対応するラベルの値と、そのラベルが存在するかを示すブール値をctxから返します。

func SetGoroutineLabels added in v1.9.0

func SetGoroutineLabels(ctx context.Context)

SetGoroutineLabelsは現在のゴルーチンのラベルをctxと一致させます。 新しいゴルーチンは、その作成元のゴルーチンのラベルを継承します。 これは、可能な場合は代わりに使用するべき Do よりも低レベルのAPIです。

func StartCPUProfile

func StartCPUProfile(w io.Writer) error

StartCPUProfileは現在のプロセスに対してCPUプロファイリングを有効にします。 プロファイリング中は、プロファイルがバッファリングされ、wに書き込まれます。 StartCPUProfileは、すでにプロファイリングが有効な場合にエラーを返します。

Unix系システムでは、-buildmode=c-archiveまたは-buildmode=c-sharedで ビルドされたGoコードでは、デフォルトではStartCPUProfileは動作しません。 StartCPUProfileはSIGPROFシグナルを利用していますが、 そのシグナルはGoが使用するものではなく、 メインプログラムのSIGPROFシグナルハンドラ(あれば)に送信されます。 関数 os/signal.Notifysyscall.SIGPROF に対して呼び出すことで、 それが動作するようにすることができますが、その場合、 メインプログラムで実行されているプロファイリングが壊れる可能性があります。

func StopCPUProfile

func StopCPUProfile()

StopCPUProfileは現在のCPUプロファイルを停止します(もし存在する場合)。 StopCPUProfileはプロファイルの書き込みが完了するまでのみ戻ります。

func WithLabels added in v1.9.0

func WithLabels(ctx context.Context, labels LabelSet) context.Context

WithLabelsは指定されたラベルが追加された新しい context.Context を返します。 ラベルは同じキーを持つ以前のラベルを上書きします。

func WriteHeapProfile

func WriteHeapProfile(w io.Writer) error

WriteHeapProfileは、Lookup("heap").WriteTo(w, 0)の略記です。 後方互換性のために保持されています。

Types

type LabelSet added in v1.9.0

type LabelSet struct {
	// contains filtered or unexported fields
}

LabelSetはラベルのセットです。

func Labels added in v1.9.0

func Labels(args ...string) LabelSet

Labelsは、キーと値のペアを表す文字列の偶数個を受け取り、それらを含む LabelSet を作成します。 ラベルは、同じキーを持つ以前のラベルを上書きします。 現在、CPUプロファイルとゴルーチンプロファイルのみがラベル情報を利用しています。 詳細は、https://golang.org/issue/23458 を参照してください。

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、 StartCPUProfileStopCPUProfile 関数があります。

Heap profile

ヒーププロファイルは、最も最近に完了したガベージコレクション時点での 統計を報告します。ライブデータから離れてガベージに偏ることを避けるために、 より最近の割り当てを除外します。 ガベージコレクションがまったく行われていない場合、ヒーププロファイルは すべての既知の割り当てを報告します。この例外は主に、ガベージコレクション なしで実行されているプログラム(通常はデバッグ目的)で役立ちます。

ヒーププロファイルは、アプリケーションメモリ内のすべてのライブオブジェクトと、 プログラム開始以降に割り当てられたすべてのオブジェクトの両方の 割り当てサイトを追跡します。 Pprofの -inuse_space、-inuse_objects、-alloc_space、-alloc_objects フラグによってどれを表示するかを選択し、デフォルトは -inuse_space(ライブオブジェクト、 サイズでスケール)です。

Allocs profile

allocsプロファイルはヒーププロファイルと同じですが、デフォルトのpprof表示を -alloc_space、つまりプログラム開始以降に割り当てられた総バイト数 (ガベージコレクションされたバイトを含む)に変更します。

Block profile

ブロックプロファイルは、sync.Mutexsync.RWMutexsync.WaitGroupsync.Cond、およびチャネル送信/受信/selectなどの同期プリミティブで ブロックされた時間を追跡します。

スタックトレースは、ブロックした場所(例:sync.Mutex.Lock)に対応します。

サンプル値は、そのスタックトレースでブロックされた累積時間に対応し、 runtime.SetBlockProfileRate によって指定される時間ベースのサンプリングに 従います。

Mutex profile

ミューテックスプロファイルは、sync.Mutexsync.RWMutex、 およびランタイム内部ロックなどのミューテックスでの競合を追跡します。

スタックトレースは、競合を引き起こしたクリティカルセクションの終わりに対応します。 例えば、他のゴルーチンがロックの取得を待っている間に長時間保持されたロックは、 ロックが最終的に解放されたときに競合を報告します(つまり、sync.Mutex.Unlock で)。

サンプル値は、他のゴルーチンがロックを待ってブロックされた 概算の累積時間に対応し、runtime.SetMutexProfileFraction によって 指定されるイベントベースのサンプリングに従います。例えば、呼び出し元が 5つの他のゴルーチンが1秒全体でロックの取得を待っている間に1秒間ロックを 保持した場合、そのアンロック呼び出しスタックは5秒の競合を報告します。

func Lookup

func Lookup(name string) *Profile

Lookupは指定された名前のプロフィールを返します。存在しない場合はnilを返します。

func NewProfile

func NewProfile(name string) *Profile

NewProfileは指定された名前で新しいプロファイルを作成します。 すでにその名前のプロファイルが存在する場合、NewProfileはパニックを引き起こします。 各パッケージごとに別の名前空間を作成するために、'import/path.'接頭辞を使用するのが一般的です。 pprofデータを読み取るさまざまなツールとの互換性のために、プロファイル名にはスペースを含めないでください。

func Profiles

func Profiles() []*Profile

Profilesは、名前でソートされたすべてのプロフィールのスライスを返します。

func (*Profile) Add

func (p *Profile) Add(value any, skip int)

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) Count

func (p *Profile) Count() int

Countは現在のプロファイル内の実行スタックの数を返します。

func (*Profile) Name

func (p *Profile) Name() string

Nameはこのプロフィールの名前を返します。プロフィールを再取得するために Lookup に渡すことができます。

func (*Profile) Remove

func (p *Profile) Remove(value any)

Removeはプロファイルから関連付けられた実行スタックを削除します。 valueがプロファイルに存在しない場合、何もしません。

func (*Profile) WriteTo

func (p *Profile) WriteTo(w io.Writer, debug int) error

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プログラムが回復不可能なパニックによって終了する際に使用する同じ形式で表示することを意味します。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL