Golang中如何追踪goroutine的内存分配情况
Golang中如何追踪goroutine的内存分配情况 我尝试使用 Go 运行时,以便在任何 Go 代码中无缝添加内存(字节、对象、分配调用)追踪功能。请在仓库 https://github.com/1pkg/gotcha 和博客文章 https://1pkg.github.io/posts/lets_trace_goroutine_allocated_memory/ 中查看详情。
1 回复
更多关于Golang中如何追踪goroutine的内存分配情况的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中追踪goroutine的内存分配情况,可以通过结合runtime包和自定义追踪器来实现。以下是一个示例代码,展示如何捕获每个goroutine的内存分配信息:
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
// 定义内存分配追踪器结构
type AllocTracker struct {
mu sync.Mutex
allocs map[uint64]uint64 // goroutine id -> 分配字节数
}
func NewAllocTracker() *AllocTracker {
return &AllocTracker{
allocs: make(map[uint64]uint64),
}
}
// 开始追踪goroutine的内存分配
func (t *AllocTracker) Start() {
go func() {
for {
t.mu.Lock()
// 获取当前goroutine的ID(通过runtime.Stack)
buf := make([]byte, 64)
n := runtime.Stack(buf, false)
stack := string(buf[:n])
// 解析goroutine ID(简化示例,实际需更健壮的解析)
var goroutineID uint64
fmt.Sscanf(stack, "goroutine %d", &goroutineID)
// 获取当前goroutine的内存分配统计
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
t.allocs[goroutineID] = memStats.TotalAlloc
t.mu.Unlock()
time.Sleep(100 * time.Millisecond) // 每100ms采样一次
}
}()
}
// 获取指定goroutine的分配内存(字节)
func (t *AllocTracker) GetAlloc(goroutineID uint64) uint64 {
t.mu.Lock()
defer t.mu.Unlock()
return t.allocs[goroutineID]
}
func main() {
tracker := NewAllocTracker()
tracker.Start()
var wg sync.WaitGroup
wg.Add(2)
// 启动示例goroutine
go func() {
defer wg.Done()
// 模拟内存分配
data := make([]byte, 1024*1024) // 分配1MB
_ = data
time.Sleep(500 * time.Millisecond)
// 输出当前goroutine分配内存
fmt.Printf("Goroutine 1 allocated: %d bytes\n", tracker.GetAlloc(1))
}()
go func() {
defer wg.Done()
// 模拟更多内存分配
for i := 0; i < 10; i++ {
_ = make([]byte, 512*1024) // 每次分配512KB
time.Sleep(50 * time.Millisecond)
}
fmt.Printf("Goroutine 2 allocated: %d bytes\n", tracker.GetAlloc(2))
}()
wg.Wait()
}
此代码创建了一个内存分配追踪器,周期性采样各goroutine的内存分配情况。通过runtime.Stack获取goroutine ID,并结合runtime.ReadMemStats读取内存统计。注意:实际应用中需要更精确的goroutine ID解析,且频繁采样可能影响性能。
对于更细粒度的控制,可参考runtime.MemProfileRate设置内存剖析速率,或使用pprof工具进行深度分析。

