pprof.StartCPUProfile未生成文件是因为必须显式调用pprof.StopCPUProfile才能写入磁盘,常见错误包括panic退出、defer位置错误、未Close文件或Windows路径权限不足。

pprof.StartCPUProfile 为什么没生成 profile 文件
调用 pprof.StartCPUProfile 后没看到文件,大概率是没调用 pprof.StopCPUProfile——它不会自动 flush,必须显式停止才能写入磁盘。常见错误包括程序 panic 退出、defer 写错位置导致没执行到 stop、或 *os.File 忘记 Close()。
- 确保
pprof.StartCPUProfile和pprof.StopCPUProfile成对出现,后者必须在defer中或明确路径上执行 - 不要依赖进程退出自动保存:Go 的
runtime/pprof不会做这事 - Windows 下注意路径权限,避免写到
C:\Program Files\这类受限目录
手动控制采样区间时如何避免采样失真
HTTP 方式(/debug/pprof/profile?seconds=30)适合 Web 服务,但对 CLI 工具、短生命周期任务或需精准定位某段逻辑的场景,pprof.StartCPUProfile 更可靠——前提是采样窗口得“包住真实负载”。
- 在业务逻辑前调用
pprof.StartCPUProfile(f),结束后立即pprof.StopCPUProfile();中间别夹杂大量阻塞操作(如未超时的time.Sleep或空闲select{}) - 若目标逻辑本身耗时短(如毫秒级),可循环多次再采样,否则信号采样可能漏掉热点
- 避免在本地 macOS 上分析:其
SIGPROF支持弱,Linux 或容器环境更准;Docker 里记得加--cap-add=SYS_PTRACE
生成的 cpu.pprof 为什么看不到函数名,全是 ???
根本原因是二进制缺少调试符号(DWARF info),常见于用 -ldflags="-s -w" 构建的发布版程序——这些 flag 会剥离符号表,导致 pprof 无法映射到源码函数。
- 开发/分析阶段禁用
-s(strip symbol table)和-w(omit DWARF symbol table) - 构建命令应为:
go build -o app main.go(不加-ldflags) - 验证是否含符号:
readelf -S ./app | grep debug或file ./app中含with debug_info即可
flat% 和 cum% 差距极大,说明什么
flat% 是函数自身耗时占比(不含调用子函数),cum% 是从当前函数到叶子节点的累计耗时。两者差得多,说明这个函数主要是“转发”或“调度”,真正干活的在它调用的下游里。
立即学习“go语言免费学习笔记(深入)”;
- 比如
http.HandlerFunc.ServeHTTP在flat%里只占 2%,但cum%达 95%,说明瓶颈不在框架胶水层,而在 handler 内部 - 此时该用
top -cum查调用链顶端,再配合list 函数名定位具体行号 - 若
json.Marshal出现在flat%高位,先确认它是否在 hot path 循环里被反复调用,而不是急着换库
cpu.pprof 就只是个带地址的空壳。



















