GO内存RSS占用过高

前言:最近解决了一个项目中go的内存占用过高的问题,由于本人也是初学这门语言所以在问题排查和定位过程中也尝试了很多方法,同时也发现目前网上对于go这么语言的一些问题排查资料很少,所以整理一下自己在排查过程中的思路。

问题表象

最近发现服务被部署后很快会出现内存积压的问题,并且将内存打满。而这个服务使用的依旧是旧的镜像版本,所以可以排除新代码上线引入的问题。

发现问题后开始排查

俗话说,选好工具是成功的一半,所以我们先说一下go的内存分析工具

首先我们要说一下go的内存分析工具----pprof。具体工具使用可以看我的另一篇文章,在此不在赘述

工具使用介绍完毕,下面开始排查问题

首先通过命令查询内存分配

root@sns-ads-service06:~/pprof# go tool pprof -inuse_space http://localhost:6060/debug/pprof/heap
Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap
Saved profile in /root/pprof/pprof.thriftcapture.alloc_objects.alloc_space.inuse_objects.inuse_space.003.pb.gz
File: thriftcapture
Build ID: 1da7c49a46e05f63089a7eecbe14129ad3948566
Type: inuse_space
Time: Apr 14, 2022 at 1:51am (UTC)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 9034.64kB, 100% of 9034.64kB total
Showing top 10 nodes out of 23
      flat  flat%   sum%        cum   cum%
 5120.23kB 56.67% 56.67%  5120.23kB 56.67%  main.CopyMulty
 2368.33kB 26.21% 82.89%  2368.33kB 26.21%  github.com/buger/goreplay/raw_socket_listener.NewListener
 1034.03kB 11.45% 94.33%  1034.03kB 11.45%  runtime.procresize
  512.05kB  5.67%   100%   512.05kB  5.67%  os.newFile
         0     0%   100%   512.05kB  5.67%  github.com/buger/goreplay/raw_socket_listener.(*Listener).readPcap.func1
         0     0%   100%   512.05kB  5.67%  github.com/buger/goreplay/rlog.(*RLogger).GetMemoryUsageRate
         0     0%   100%   512.05kB  5.67%  github.com/buger/goreplay/rlog.(*logWriter).ReadFile
         0     0%   100%  2368.33kB 26.21%  main.(*RAWInput).listen
         0     0%   100%  2368.33kB 26.21%  main.InitPlugins
         0     0%   100%  2368.33kB 26.21%  main.NewRAWInput
(pprof) root@sns-ads-service06:~/pprof# 

发现没有大的内存占用

然后换一是否是goroutine 泄漏,通过命令获取 goroutine信息

root@sns-ads-service06:/usr/bin# wget -O - http://localhost:6060/debug/pprof/goroutine?debug=1
--2022-04-16 03:50:10--  http://localhost:6060/debug/pprof/goroutine?debug=1
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:6060... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/plain]
Saving to: 'STDOUT'


goroutine 98 [chan receive, 8 minutes]:
github.com/buger/goreplay/rlog.(*logWriter).runCacheWrite(0xc00011c000)
	/go/src/goreplay/rlog/writer.go:397 +0x7d
created by github.com/buger/goreplay/rlog.(*logWriter).initLogWriter
	/go/src/goreplay/rlog/writer.go:172 +0x15b

goroutine 99 [chan receive, 8 minutes]:
github.com/buger/goreplay/raw_socket_listener.(*Listener).sendMsg(0xc0000eaea0)
	/go/src/goreplay/raw_socket_listener/listener.go:176 +0x59
created by github.com/buger/goreplay/raw_socket_listener.NewListener
	/go/src/goreplay/raw_socket_listener/listener.go:130 +0x2fa

goroutine 100 [chan receive, 8 minutes]:
github.com/buger/goreplay/raw_socket_listener.(*Listener).sendMsg(0xc0000eaea0)
	/go/src/goreplay/raw_socket_listener/listener.go:176 +0x59
created by github.com/buger/goreplay/raw_socket_listener.NewListener
	/go/src/goreplay/raw_socket_listener/listener.go:130 +0x2fa

发现进程执行也是正常的,因为代码中用到了一些chan,但并没有阻塞的情况

查询内存使用情况

$top
top - 01:56:27 up 36 days,  1:48,  0 users,  load average: 11.97, 13.52, 22.38
Tasks:   5 total,   1 running,   4 sleeping,   0 stopped,   0 zombie
%Cpu(s): 16.0 us,  3.0 sy,  0.0 ni, 79.7 id,  0.0 wa,  0.0 hi,  1.4 si,  0.0 st
MiB Mem : 126289.6 total,  88208.2 free,  18361.2 used,  19720.2 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used. 107171.1 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                                                                                          
      6 root      20   0 8194872   2.0g  25584 S 101.3   1.7   6:47.79 server                                                                                                                                                                    
      1 root      20   0    3828   2848   2608 S   0.0   0.0   0:00.00 demo                                                                                                                                                                    
     72 root      20   0    4092   3408   2876 S   0.0   0.0   0:00.00 bash                                                                                                                                                                             
    104 root      20   0    4092   3312   2880 S   0.0   0.0   0:00.00 bash                                                                                                                                                                             
    110 root      20   0    6940   3240   2748 R   0.0   0.0   0:00.00 top

发现虽然内存分配不多,但是RES确实有很高的值、难道是因为RSS没有被回收

继续查找原因

 (runtime: provide way to disable MADV_FREE · Issue #28466 · golang/go · GitHub

如上issue所述,难道是GC策略的问题,感觉试一下

添加环境变量:GODEBUG=madvdontneed=1

然后提交代码,等待镜像打包,然后打包失败了。。。。

Step 4/16 : RUN git config --global url."git@code.devops.xiaohongshu.com:".insteadof "http://code.devops.xiaohongshu.com/" &&     go env -w GO111MODULE=on &&     go env -w GOSUMDB=off &&     go env -w GOPROXY=https://goproxy.cn,direct &&     go env -w GOPRIVATE=code.devops.xiaohongshu.com     go env -w GODEBUG='madvdontneed=1'
 ---> Running in b74d9e5c4fa8
go env -w: arguments must be KEY=VALUE: invalid argument: go

 基于我比较懒,所以想看看有没有别的办法

还真有

 原来在Go1.16版本已经修复了这个问题

然后就是升级包版本,然后打包,构架镜像,部署,验证。

果然内存的问题有一定的缓解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值