diff --git a/internal/server/pprof.go b/internal/server/pprof.go index 4aa1778..0de80a9 100644 --- a/internal/server/pprof.go +++ b/internal/server/pprof.go @@ -131,6 +131,8 @@ func (h *PprofHandler) ServeHTTP(ctx *fasthttp.RequestCtx) { h.handleBlock(ctx) case "/mutex": h.handleMutex(ctx) + case "/allocs": + h.handleAllocs(ctx) default: ctx.SetStatusCode(fasthttp.StatusNotFound) ctx.SetBodyString("Unknown profile: " + subPath) @@ -175,7 +177,8 @@ func (h *PprofHandler) handleIndex(ctx *fasthttp.RequestCtx) {

Pprof Profiles

- + + @@ -183,7 +186,7 @@ func (h *PprofHandler) handleIndex(ctx *fasthttp.RequestCtx) {

Usage: curl %s/profile?seconds=30 > cpu.pgo

` - ctx.SetBodyString(fmt.Sprintf(html, h.path, h.path, h.path, h.path, h.path, h.path)) + ctx.SetBodyString(fmt.Sprintf(html, h.path, h.path, h.path, h.path, h.path, h.path, h.path)) } // handleCPU 处理 CPU profile 请求。 @@ -267,7 +270,7 @@ func (h *PprofHandler) handleBlock(ctx *fasthttp.RequestCtx) { // 采集互斥锁竞争的 profile 数据并返回。 // // 参数: -// - ctx: fasthttp 请求上下文,用于写入响应 +// - ctx: 请求上下文,用于写入响应 func (h *PprofHandler) handleMutex(ctx *fasthttp.RequestCtx) { ctx.SetContentType("application/octet-stream") ctx.SetBodyStreamWriter(func(w *bufio.Writer) { @@ -275,3 +278,18 @@ func (h *PprofHandler) handleMutex(ctx *fasthttp.RequestCtx) { _ = w.Flush() }) } + +// handleAllocs 处理内存分配 profile 请求。 +// +// 返回与 heap 同源但以分配视角展示的 profile 数据, +// 等价于 net/http/pprof 的 /debug/pprof/allocs。 +// +// 参数: +// - ctx: 请求上下文,用于写入响应 +func (h *PprofHandler) handleAllocs(ctx *fasthttp.RequestCtx) { + ctx.SetContentType("application/octet-stream") + ctx.SetBodyStreamWriter(func(w *bufio.Writer) { + writeAllocsProfile(wrapBufioWriter(w)) + _ = w.Flush() + }) +} diff --git a/internal/server/pprof_impl.go b/internal/server/pprof_impl.go index 3fe4cba..fb03773 100644 --- a/internal/server/pprof_impl.go +++ b/internal/server/pprof_impl.go @@ -131,6 +131,24 @@ func writeMutexProfile(w io.Writer) { } } +// writeAllocsProfile 写入分配 profile。 +// +// 与 heap profile 使用同一份数据,但默认以分配视角展示(Samples=alloc_*)。 +// 等价于 net/http/pprof 的 /debug/pprof/allocs。 +// +// 参数: +// - w: 输出 writer,用于写入 profile 数据 +func writeAllocsProfile(w io.Writer) { + p := pprof.Lookup("allocs") + if p != nil { + _ = p.WriteTo(w, 0) + return + } + // 如果 allocs profile 未注册,回退到 heap profile + runtime.GC() + _ = pprof.WriteHeapProfile(w) +} + // bufioWriterAdapter 将 bufio.Writer 包装为 io.Writer,自动 Flush。 // // 该结构体实现 io.Writer 接口,在每次写入后自动调用 Flush,
CPU Profile (30s)CPU profile for 30 seconds
Heap ProfileMemory allocation profile
Heap ProfileMemory allocation profile (in-use)
Allocs ProfileMemory allocation profile (allocations)
Goroutine ProfileGoroutine stack traces
Block ProfileBlocking profile
Mutex ProfileMutex contention profile