it编程 > 前端脚本 > Golang

Go net/http/pprof分析内存泄露及解决过程

3人参与 2025-04-24 Golang

内存泄露出现的原因

在go语言中,其自身实现了 gc(垃圾回收)机制, 所有出现内存泄露的原因很大可能是 有些goroutine因为各种各样的原因(如 channel阻塞或未设置close channel的功能)导致 垃圾回收机制 认为这些goroutine还在正常运行,无法被回收(每个goroutine至少占用2kb资源),长时间处理大量请求后,导致内存耗尽。

业务大致场景

go语言编写的kong插件中,出现内存泄露。

分析方法

嵌入如下代码; 即使是在 go脚本中,通过如下代码,也会生成一个pprof的http服务,供web端分析使用。

import "github.com/kong/go-pdk/server"
import _ "net/http/pprof"


// main 主入口函数,启动go-pdk中的server
func main() {
	// 服务资源分析时使用
	go func() {
		err := http.listenandserve("0.0.0.0:6000", nil)
		if err != nil {
			panic("启动服务失败")
		}
	}()

	err := server.startserver(new, version, priority)
	if err != nil {
		panic(err)
	}
}

运行服务,并 查看 http://localhost:6000/debug/pprof/goroutine?debug=1 分析方式如下:

压测请求此服务; 对比发现 协程个数不断增加的地方;从而找到内存泄露点;

具体原因

最终发现 是 链路追踪的jaeger reporter(导出span数据到jaeger中)每次请求进入都新建一个协程,导致内存泄露

解决方法

通过 全局变量+ sync.once 保证 只生成一个 jaeger reporter;从而 不会生成多个协程,及 节约 网络io资源。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

Go语言Slice切片底层的实现

04-24

如何使用Golang打包jar应用

04-24

Go语言实现权重抽奖系统的项目实践

04-24

go语言使用range来接收通道里面的数据

04-24

go协程池实现原理小结

04-24

一文带你学会使用Go语言实现自己的MCP服务端

04-24

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论