可直接调用pprof.Lookup("profile").WriteTo或runtime/pprof.StartCPUProfile/StopCPUProfile写入文件,无需HTTP;CPU profile需成对调用,heap profile需在内存高峰后显式GC再采集。

pprof数据怎么不走HTTP直接写入文件
Go 的 net/http/pprof 默认绑定在 HTTP handler 上,但你不需要启动 HTTP 服务也能获取 pprof 数据——关键在于直接调用 pprof 包的导出函数,绕过 HTTP 中间层。
常见误区是以为必须用 curl http://localhost:6060/debug/pprof/profile 才能拿到数据,其实 pprof.Lookup + WriteTo 就能本地生成原始 profile 文件。
-
runtime/pprof.StartCPUProfile和StopCPUProfile是最可控的方式,适合定时或条件触发的 CPU 采样 - 内存、goroutine、block 等 profile 需用
pprof.Lookup("heap")等方式获取快照,再写入文件 - 注意:CPU profile 必须成对调用
Start/Stop,否则WriteTo会返回空或 panic
写 CPU profile 到文件的最小可行代码
下面这段代码不依赖 HTTP,直接写 cpu.pprof:
package main
<p>import (
"os"
"runtime/pprof"
"time"
)</p><p>func main() {
f, _ := os.Create("cpu.pprof")
defer f.Close()</p><pre class="brush:php;toolbar:false;">pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
// 模拟一些工作
time.Sleep(2 * time.Second)}
立即学习“go语言免费学习笔记(深入)”;
运行后生成的 cpu.pprof 是二进制格式,可用命令行工具分析:go tool pprof cpu.pprof。别用文本编辑器打开,它不是 JSON 或文本。
写 heap profile 时为什么经常得到空文件
heap profile 是瞬时快照,不像 CPU profile 是持续采集。如果程序没分配太多堆内存,或者 GC 尚未触发,Lookup("heap").WriteTo 可能只写入极小数据(甚至 0 字节)。
- 确保在内存分配高峰后立即采集,比如在批量处理完数据、GC 运行后调用
- 显式触发 GC:
runtime.GC(),再等一小会儿,再pprof.Lookup("heap").WriteTo(f, 0) - 第二个参数是
debug级别:0是默认二进制格式;1输出可读的文本摘要(不推荐存档,仅调试) - 别漏掉
os.O_CREATE | os.O_WRONLY | os.O_TRUNC打开文件,否则可能写失败且无提示
如何安全地在生产服务中自动 dump profile
不能让 StartCPUProfile 一直开着——它有性能开销(约 5%~10%),且文件会无限增长。更稳妥的做法是响应信号或定时短时采样。
- 监听
SIGUSR1:收到信号后启动 30 秒 CPU profile,写入带时间戳的文件(如cpu_20240520_142315.pprof) - 用
runtime.SetBlockProfileRate控制 block profile 精度,避免高频锁竞争导致文件暴增 - 所有写文件操作务必加
defer f.Close()和错误检查,pprof 不报错但写入失败时文件为空 - profile 文件包含符号信息,但若二进制是 stripped 的(比如用
-ldflags="-s -w"编译),go tool pprof将无法显示函数名
真正麻烦的从来不是“怎么写进去”,而是“什么时候写、写什么、写完怎么解读”。文件生成只是第一步,后续是否能定位到热点,取决于采集时机和二进制的调试信息完整性。



















