Source File
pprof.go
Belonging Package
runtime/pprof
package pprof
import (
)
var profiles struct {
mu sync.Mutex
m map[string]*Profile
}
var goroutineProfile = &Profile{
name: "goroutine",
count: countGoroutine,
write: writeGoroutine,
}
var threadcreateProfile = &Profile{
name: "threadcreate",
count: countThreadCreate,
write: writeThreadCreate,
}
var heapProfile = &Profile{
name: "heap",
count: countHeap,
write: writeHeap,
}
var allocsProfile = &Profile{
name: "allocs",
count: countHeap, // identical to heap profile
write: writeAlloc,
}
var blockProfile = &Profile{
name: "block",
count: countBlock,
write: writeBlock,
}
var mutexProfile = &Profile{
name: "mutex",
count: countMutex,
write: writeMutex,
}
func () {
profiles.mu.Lock()
profiles.m = map[string]*Profile{
"goroutine": goroutineProfile,
"threadcreate": threadcreateProfile,
"heap": heapProfile,
"allocs": allocsProfile,
"block": blockProfile,
"mutex": mutexProfile,
}
}
}
func () {
profiles.mu.Unlock()
}
func ( string) *Profile {
lockProfiles()
defer unlockProfiles()
return profiles.m[]
}
sort.Slice(, func(, int) bool {
, := [], []
for := 0; < len() && < len(); ++ {
if [] != [] {
return [] < []
}
}
return len() < len()
})
return printCountProfile(, , .name, stackProfile())
}
type stackProfile [][]uintptr
func ( stackProfile) () int { return len() }
func ( stackProfile) ( int) []uintptr { return [] }
func ( stackProfile) ( int) *labelMap { return nil }
:= newProfileBuilder()
.pbValueType(tagProfile_PeriodType, , "count")
.pb.int64Opt(tagProfile_Period, 1)
.pbValueType(tagProfile_SampleType, , "count")
.pbValueType(tagProfile_SampleType, , "nanoseconds")
:= float64(runtime_cyclesPerSecond()) / 1e9
:= []int64{0, 0}
var []uint64
for , := range {
, := (.Count, float64(.Cycles)/)
[0] =
var bytes.Buffer
:= func( []uintptr, *labelMap) string {
.Reset()
fmt.Fprintf(&, "@")
for , := range {
fmt.Fprintf(&, " %#x", )
}
if != nil {
.WriteString("\n# labels: ")
.WriteString(.String())
}
return .String()
}
:= map[string]int{}
:= map[string]int{}
var []string
:= .Len()
for := 0; < ; ++ {
:= (.Stack(), .Label())
if [] == 0 {
[] =
= append(, )
}
[]++
}
sort.Sort(&keysByCount{, })
:= newProfileBuilder()
.pbValueType(tagProfile_PeriodType, , "count")
.pb.int64Opt(tagProfile_Period, 1)
.pbValueType(tagProfile_SampleType, , "count")
:= []int64{0}
var []uint64
for , := range {
= .appendLocsForStack([:0], .Stack([]))
:= []
var func()
if .Label() != nil {
= func() {
for , := range *.Label() {
.pbLabel(tagSample_Label, , , 0)
}
}
}
.pbSample(, , )
}
.build()
return nil
}
func () int {
, := runtime.MemProfile(nil, true)
return
}
func ( io.Writer, int) error {
return writeHeapInternal(, , "")
}
= new(runtime.MemStats)
runtime.ReadMemStats()
}
var []runtime.MemProfileRecord
, := runtime.MemProfile(nil, true)
= make([]runtime.MemProfileRecord, +50)
, = runtime.MemProfile(, true)
if {
= [0:]
break
}
if == 0 {
return writeHeapProto(, , int64(runtime.MemProfileRate), )
}
sort.Slice(, func(, int) bool { return [].InUseBytes() > [].InUseBytes() })
:= bufio.NewWriter()
:= tabwriter.NewWriter(, 1, 8, 1, '\t', 0)
=
var runtime.MemProfileRecord
for := range {
:= &[]
.AllocBytes += .AllocBytes
.AllocObjects += .AllocObjects
.FreeBytes += .FreeBytes
.FreeObjects += .FreeObjects
}
fmt.Fprintf(, "heap profile: %d: %d [%d: %d] @ heap/%d\n",
.InUseObjects(), .InUseBytes(),
.AllocObjects, .AllocBytes,
2*runtime.MemProfileRate)
for := range {
:= &[]
fmt.Fprintf(, "%d: %d [%d: %d] @",
.InUseObjects(), .InUseBytes(),
.AllocObjects, .AllocBytes)
for , := range .Stack() {
fmt.Fprintf(, " %#x", )
}
fmt.Fprintf(, "\n")
printStackRecord(, .Stack(), false)
}
:=
fmt.Fprintf(, "\n# runtime.MemStats\n")
fmt.Fprintf(, "# Alloc = %d\n", .Alloc)
fmt.Fprintf(, "# TotalAlloc = %d\n", .TotalAlloc)
fmt.Fprintf(, "# Sys = %d\n", .Sys)
fmt.Fprintf(, "# Lookups = %d\n", .Lookups)
fmt.Fprintf(, "# Mallocs = %d\n", .Mallocs)
fmt.Fprintf(, "# Frees = %d\n", .Frees)
fmt.Fprintf(, "# HeapAlloc = %d\n", .HeapAlloc)
fmt.Fprintf(, "# HeapSys = %d\n", .HeapSys)
fmt.Fprintf(, "# HeapIdle = %d\n", .HeapIdle)
fmt.Fprintf(, "# HeapInuse = %d\n", .HeapInuse)
fmt.Fprintf(, "# HeapReleased = %d\n", .HeapReleased)
fmt.Fprintf(, "# HeapObjects = %d\n", .HeapObjects)
fmt.Fprintf(, "# Stack = %d / %d\n", .StackInuse, .StackSys)
fmt.Fprintf(, "# MSpan = %d / %d\n", .MSpanInuse, .MSpanSys)
fmt.Fprintf(, "# MCache = %d / %d\n", .MCacheInuse, .MCacheSys)
fmt.Fprintf(, "# BuckHashSys = %d\n", .BuckHashSys)
fmt.Fprintf(, "# GCSys = %d\n", .GCSys)
fmt.Fprintf(, "# OtherSys = %d\n", .OtherSys)
fmt.Fprintf(, "# NextGC = %d\n", .NextGC)
fmt.Fprintf(, "# LastGC = %d\n", .LastGC)
fmt.Fprintf(, "# PauseNs = %d\n", .PauseNs)
fmt.Fprintf(, "# PauseEnd = %d\n", .PauseEnd)
fmt.Fprintf(, "# NumGC = %d\n", .NumGC)
fmt.Fprintf(, "# NumForcedGC = %d\n", .NumForcedGC)
fmt.Fprintf(, "# GCCPUFraction = %v\n", .GCCPUFraction)
fmt.Fprintf(, "# DebugGC = %v\n", .DebugGC)
func () int {
, := runtime.ThreadCreateProfile(nil)
return
}
return writeRuntimeProfile(, , "threadcreate", func( []runtime.StackRecord, []unsafe.Pointer) ( int, bool) {
return runtime.ThreadCreateProfile()
})
}
func () int {
return runtime.NumGoroutine()
}
func ( io.Writer, int) error {
if >= 2 {
return writeGoroutineStacks()
}
return writeRuntimeProfile(, , "goroutine", runtime_goroutineProfileWithLabels)
}
}
return printCountProfile(, , , &runtimeProfile{, })
}
type runtimeProfile struct {
stk []runtime.StackRecord
labels []unsafe.Pointer
}
func ( *runtimeProfile) () int { return len(.stk) }
func ( *runtimeProfile) ( int) []uintptr { return .stk[].Stack() }
func ( *runtimeProfile) ( int) *labelMap { return (*labelMap)(.labels[]) }
var cpu struct {
sync.Mutex
profiling bool
done chan bool
}
func () ( []uint64, []unsafe.Pointer, bool)
func ( io.Writer) {
:= newProfileBuilder()
var error
for {
time.Sleep(100 * time.Millisecond)
, , := readProfile()
if := .addCPUData(, ); != nil && == nil {
=
}
if {
break
}
}
func () int {
, := runtime.BlockProfile(nil)
return
}
func () int {
, := runtime.MutexProfile(nil)
return
}
func ( io.Writer, int) error {
var []runtime.BlockProfileRecord
, := runtime.BlockProfile(nil)
for {
= make([]runtime.BlockProfileRecord, +50)
, = runtime.BlockProfile()
if {
= [:]
break
}
}
sort.Slice(, func(, int) bool { return [].Cycles > [].Cycles })
if <= 0 {
return printCountCycleProfile(, "contentions", "delay", scaleBlockProfile, )
}
:= bufio.NewWriter()
:= tabwriter.NewWriter(, 1, 8, 1, '\t', 0)
=
fmt.Fprintf(, "--- contention:\n")
fmt.Fprintf(, "cycles/second=%v\n", runtime_cyclesPerSecond())
for := range {
:= &[]
fmt.Fprintf(, "%v %v @", .Cycles, .Count)
for , := range .Stack() {
fmt.Fprintf(, " %#x", )
}
fmt.Fprint(, "\n")
if > 0 {
printStackRecord(, .Stack(), true)
}
}
if != nil {
.Flush()
}
return .Flush()
}
return ,
}
var []runtime.BlockProfileRecord
, := runtime.MutexProfile(nil)
for {
= make([]runtime.BlockProfileRecord, +50)
, = runtime.MutexProfile()
if {
= [:]
break
}
}
sort.Slice(, func(, int) bool { return [].Cycles > [].Cycles })
if <= 0 {
return printCountCycleProfile(, "contentions", "delay", scaleMutexProfile, )
}
:= bufio.NewWriter()
:= tabwriter.NewWriter(, 1, 8, 1, '\t', 0)
=
fmt.Fprintf(, "--- mutex:\n")
fmt.Fprintf(, "cycles/second=%v\n", runtime_cyclesPerSecond())
fmt.Fprintf(, "sampling period=%d\n", runtime.SetMutexProfileFraction(-1))
for := range {
:= &[]
fmt.Fprintf(, "%v %v @", .Cycles, .Count)
for , := range .Stack() {
fmt.Fprintf(, " %#x", )
}
fmt.Fprint(, "\n")
if > 0 {
printStackRecord(, .Stack(), true)
}
}
if != nil {
.Flush()
}
return .Flush()
}
func ( int64, float64) (int64, float64) {
:= runtime.SetMutexProfileFraction(-1)
return * int64(), * float64()
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |