profile采样的实现
profiling 工具基本分两种思路:
插桩
具体实现方式就是在每个函数的开始和结束时计时,然后统计每个函数的执行时间。
插桩计时本身也会带来性能消耗,并且对于正在运行的程序没办法插桩。
采样
具体实现是注入正在运行的进程,高频地去探测函数调用栈。根据大数定律探测次数越多的函数运行时间越长。
perf、pprof工具都是这个思路
CPU profiling
开启采样
// runtime/pprof/pprof.go
// 开启CPU采样,并设置频率
func StartCPUProfile(w io.Writer) error {
cpu.profiling = true
runtime.SetCPUProfileRate(hz)
go profileWriter(w)
}收集采样
程序在启动时会注册对 SIGPROF 信号的监听,收到该信号后就会开始采样。采样逻辑是收集栈调用信息,从中分析出当前正在执行的函数及其调用链,并记录到 cpuprof.log 的 buffer 缓存中
**疑问:**只看到处理 SIGPROF 的地方,没有看到发送的地方
将采样结果写入文件
将采样结果从 buffer 写入文件
Mem Profiling
其原理是在内存分配的时候进行采样,将分配的内存及其调用堆栈信息拷贝到一个 mbuckets 数组,然后拿这个数组做分析。
参考
Last updated