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

 更新时间:2025年04月15日 09:07:25   作者:rgc_520_zyl  
这篇文章主要介绍了Go net/http/pprof分析内存泄露及解决过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

内存泄露出现的原因

在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资源。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • golang协程关闭踩坑实战记录

    golang协程关闭踩坑实战记录

    协程(coroutine)是Go语言中的轻量级线程实现,下面这篇文章主要给大家介绍了关于golang协程关闭踩坑的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • Golang中如何使用lua进行扩展详解

    Golang中如何使用lua进行扩展详解

    这篇文章主要给大家介绍了关于Golang中如何使用lua进行扩展的相关资料,这是最近在工作中遇到的一个问题,觉着有必要分享出来给大家学习,文中给出了详细的示例,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-10-10
  • 教你一招完美解决vscode安装go插件失败问题

    教你一招完美解决vscode安装go插件失败问题

    VSCode是我们开发go程序的常用工具,但是安装VSCode成功后,创建一个.go文件居然提示错误了,所以下面下面这篇文章主要给大家介绍了如何通过一招完美解决vscode安装go插件失败问题的相关资料,需要的朋友可以参考下
    2022-07-07
  • go mod详细使用教程

    go mod详细使用教程

    go mod是go的一个模块管理工具,用来代替传统的GOPATH方案,下面这篇文章主要给大家介绍了关于go mod详细使用的相关资料,文中通过图文以及实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • 一文理解Goland协程调度器scheduler的实现

    一文理解Goland协程调度器scheduler的实现

    本文主要介绍了Goland协程调度器scheduler的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 详解Golang中channel的实现

    详解Golang中channel的实现

    channel俗称管道,用于数据传递或数据共享,其本质是一个先进先出的队列,使用goroutine+channel进行数据通讯简单高效,同时也线程安全,本文就给大家讲讲Golang中channel的实现,需要的朋友可以参考下
    2023-09-09
  • Golang 语言控制并发 Goroutine的方法

    Golang 语言控制并发 Goroutine的方法

    本文我们介绍了不同场景中分别适合哪种控制并发 goroutine 的方式,其中,channel 适合控制少量 并发 goroutine,WaitGroup 适合控制一组并发 goroutine,而 context 适合控制多级并发 goroutine,感兴趣的朋友跟随小编一起看看吧
    2021-06-06
  • Go java 算法之括号生成示例详解

    Go java 算法之括号生成示例详解

    这篇文章主要为大家介绍了Go java 算法之括号生成示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • golang封装一个执行命令行的函数(return stderr/stdout/exitcode)示例代码

    golang封装一个执行命令行的函数(return stderr/stdout/exitcode)示例代码

    在 Go 语言中,您可以使用 os/exec 包来执行外部命令,不通过调用 shell,并且能够获得进程的退出码、标准输出和标准错误输出,下面给大家分享golang封装一个执行命令行的函数(return stderr/stdout/exitcode)的方法,感兴趣的朋友跟随小编一起看看吧
    2024-06-06
  • Golang 中的 unsafe.Pointer 和 uintptr详解

    Golang 中的 unsafe.Pointer 和 uintptr详解

    这篇文章主要介绍了Golang中的unsafe.Pointer和uintptr详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-08-08

最新评论