一、内存泄漏排查

1、内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。 2、排查内存泄漏方法: 1)添加pprof包调试:http://localhost:port/debug/pprof/。 上图为网页查看,本地压测观察goroutine变化,如果压测结束后goroutine数量没有下降则证明程序存在goroutine泄漏。可查看goroutine具体信息进而定位到具体的goroutine没有释放,就可以解决goroutine泄漏。

上图为用命令行查看,查看压测这段时间内堆上累计分配的内存,具体命令是:

go tool pprof -alloc_space -cum http://localhost:port/debug/pprof/heap

使用-cum,是累计函数调用栈的堆分配大小,因为图形会将调用栈很大的路线着重标识出来。定位图片中堆分配异常然后追溯处理对应逻辑即可。 2) 开启打印gc信息 只要在程序执行之前加上环境变量GODEBUG=gctrace=1 ,如:

GODEBUG gctrace =1 ./xxxx.exe or GODEBUG gctrace =1 go run main.go

垃圾回收信息:

gc 1 @2.104s 0%: 0.018+1.3+0.076 ms clock, 0.054+0.35/1.0/3.0+0.23 ms cpu, 4->4->3 MB, 5 MB goal, 4 P
  • 1 表示第一次执行
  • @2.104s 表示程序执行的总时间
  • 0% 垃圾回收时间占用的百分比,(不知道和谁比?难道是和上面的程序执行总时间,这样比较感觉没意义)
  • 0.018+1.3+0.076 ms clock 垃圾回收的时间,分别为STW(stop-the-world)清扫的时间, 并发标记和扫描的时间,STW标记的时间
  • 0.054+0.35/1.0/3.0+0.23 ms cpu 垃圾回收占用cpu时间
  • 4->4->3 MB 堆的大小,gc后堆的大小,存活堆的大小
  • 5 MB goal 整体堆的大小
  • 4 P 使用的处理器数量

系统内存回收信息:

scvg0: inuse: 426, idle: 0, sys: 427, released: 0, consumed: 427 (MB)
  • 426 使用多少M内存
  • 0 剩下要清除的内存
  • 427 系统映射的内存
  • 0 释放的系统内存
  • 427 申请的系统内存

二、内存占用优化

1、去除无用的、重复的存储使用。 2、尽量少用map或者map中value尽量少为指针,因为GC扫描会扫描map中的指针类型,如果map中指针太多会增加GC扫描时间。 3、如果用 map 做缓存,而每次更新只是部分更新,更新的 key 如果偏差比较大,有可能会有内存逐渐增长而不释放的问题。

三、Go GC机制

1、Go语言有内存池,每次GC后只是把无用的对象放入内存池中,不会立即归还给操作系统,这样子如果还需要内存的话会优先从内存池中分配,不会向操作系统分配内存。内存池中对象如果5分钟还没有再被使用,此时则会把这些内存归还给操作系统。这两部分别为gc和scvg。 2、手动强制释放内存:

runtime.GC()
debug.FreeOSMemory()

results matching ""

    No results matching ""