Go调试神器pprof使用教程【实战分享】

news2024/9/28 9:34:01

Go调试神器pprof使用教程

go的GC会自动管理内存,但是这不代表go程序就不会内存泄露了。 go常见产生内存泄露的原因就是goroutine没有结束,简单说就是goroutine 被阻塞了,这样就会导致goroutine引用的内存不被GC回收。

1 概念

在Go中,我们可以通过标准库的代码包runtime和runtime/pprof中的程序来生成三种包含实时性数据的概要文件,分别是CPU概要文件、内存概要文件和程序阻塞概要文件。

  • CPU概要文件:默认情况下,Go的运行时系统会以100Hz的频率对CPU的使用情况进行取样
  • 内存概要文件:程序运行过程中堆内存的分配情况
  • 程序阻塞概要文件:用于保护用户程序中的Goroutine阻塞事件的记录
    • Goroutine 活跃Goroutine信息的记录 仅在获取时取样一次
    • Threadcreate 系统线程创建情况的记录 仅在获取时取样一次
    • Heap 堆内存分配情况的记录 默认每分配512K字节时取样一次
    • Block Goroutine阻塞事件的记录 默认每发生一次阻塞事件时取样一次

2 使用

前提:代码中引入pprof

package main

import "net/http"
import _ "net/http/pprof"

func main() {
    go func() {
       http.ListenAndServe("0.0.0.0:80", nil)
    }()
    select {}
}

①浏览器中查看

  1. 浏览器中输入地址localhost/debug/pprof
    在这里插入图片描述

profiles下分别是block(阻塞情况)、goroutine数量、heap(堆)、mutex(锁)和threadcreate(创建的物理线程)
点击heap可以看到如下堆内存及GC相关的参数信息

在这里插入图片描述
这里是调用Go底层的runtime.MemStats结构体获取,该结构体相关字段解释如下:

Alloc uint64 //golang语言框架堆空间分配的字节数
TotalAlloc uint64 //从服务开始运行至今分配器为分配的堆空间总 和,只有增加,释放的时候不减少
Sys uint64 //服务现在系统使用的内存
Lookups uint64 //被runtime监视的指针数
Mallocs uint64 //服务malloc heap objects的次数
Frees uint64 //服务回收的heap objects的次数
HeapAlloc uint64 //服务分配的堆内存字节数
HeapSys uint64 //系统分配的作为运行栈的内存
HeapIdle uint64 //申请但是未分配的堆内存或者回收了的堆内存(空闲)字节数
HeapInuse uint64 //正在使用的堆内存字节数
HeapReleased uint64 //返回给OS的堆内存,类似C/C++中的free。
HeapObjects uint64 //堆内存块申请的量
StackInuse uint64 //正在使用的栈字节数
StackSys uint64 //系统分配的作为运行栈的内存
MSpanInuse uint64 //用于测试用的结构体使用的字节数
MSpanSys uint64 //系统为测试用的结构体分配的字节数
MCacheInuse uint64 //mcache结构体申请的字节数(不会被视为垃圾回收)
MCacheSys uint64 //操作系统申请的堆空间用于mcache的字节数
BuckHashSys uint64 //用于剖析桶散列表的堆空间
GCSys uint64 //垃圾回收标记元信息使用的内存
OtherSys uint64 //golang系统架构占用的额外空间
NextGC uint64 //垃圾回收器检视的内存大小
LastGC uint64 // 垃圾回收器最后一次执行时间。
PauseTotalNs uint64 // 垃圾回收或者其他信息收集导致服务暂停的次数。
PauseNs [256]uint64 //一个循环队列,记录最近垃圾回收系统中断的时间
PauseEnd [256]uint64 //一个循环队列,记录最近垃圾回收系统中断的时间开始点。
NumForcedGC uint32 //服务调用runtime.GC()强制使用垃圾回收的次数。
GCCPUFraction float64 //垃圾回收占用服务CPU工作的时间总和。如果有100个goroutine,垃圾回收的时间为1S,那么就占用了100S。
BySize //内存分配器使用情况

如果觉得文字展示不够直观,我们也可以通过导入第三方组建来动态展示图表

package main

import (
	"fmt"
	_ "github.com/mkevac/debugcharts" // 可选,添加后可以查看几个实时图表数据
	"net/http"
	_ "net/http/pprof" // 必须,引入 pprof 模块
)

func main() {
	go func() {
		// terminal: $ go tool pprof -http=:8081 http://localhost:6060/debug/pprof/heap
		// web:
		// 1、http://localhost:8081/ui
		// 2、http://localhost:6060/debug/charts
		// 3、http://localhost:6060/debug/pprof
		fmt.Println(http.ListenAndServe("0.0.0.0:6060", nil))
	}()
	fmt.Println("this is a demo about how to use go pprof")
	select {}
}

输入网址:http://localhost:6060/debug/charts/

  • 查看效果

在这里插入图片描述

②go tool pprof 命令行工具

例:查看内存使用情况

# 在bash控制台执行如下命令,查看内存使用情况
> go tool pprof  http://localhost:80/debug/pprof/heap

会进入如下gdb交互模式:
在这里插入图片描述

> help可以查看使用说明
 
> top 可以查看前10个的内存分配情况
 
> tree 以树状显示
 
> png 以图片格式输出
 
> svg 生成浏览器可以识别的svg文件

例:查看cpu使用情况

> go tool pprof  http://localhost:80/debug/pprof/profile

该操作默认需要等待30s

查看其他信息同上操作。

③实战:排查线上问题(内存暴涨)

  1. 问题:内存暴涨

每天晚上八点左右,服务的内存就开始暴涨,曲线骤降的地方都是手动重启服务才降下来的,内存只要上去了就不会再降了,有时候内存激增直接打爆了内存触发了OOM。

在这里插入图片描述

  1. 有的同学可能就会说了“啊,你容器的内存是不是不够啊,开大一点不就好了?”,容器已经开到20G内存了…我们再用top看看服务内存情况:

在这里插入图片描述

让我忍不住直呼好家伙,服务进程使用的常驻内存RES居然有6G+,这明显没把我golang的gc放在眼里,该项目也没用本地缓存之类的,这样的内存占用明显不合理,没办法只好祭出我们golang内存分析利器:pprof。

  1. 有了pprof就很好办了是吧,瞬间柳暗花明啊,“这个内存泄漏我马上就能fix”,找了一天晚上八点钟,准时蹲着内存泄漏。我们直接找一台能ping通容器并且装了golang的机器,直接用下面的命令看看当前服务的内存分配情况:
$ go tool pprof -inuse_space http://ip:amdin_port/debug/pprof/heap

-inuse_space参数就是当前服务使用的内存情况
还有一个-alloc_space参数是指服务启动以来总共分配的内存情况,显然用前者比较直观,进入交互界面后我们用top命令看下当前占用内存最高的部分:

在这里插入图片描述

“结果是非常的amazing啊”,当时的内存分配最大的就是bytes.makeSlice,这个是不存在内存泄漏问题的,我们再用命令png生成分配图看看(需要装graphviz):

在这里插入图片描述
4. 看起来除了bytes.makeSlice分配内存比较大,其他好像也并没有什么问题,不行,再抓一下当前内存分配的详情:

$ wget http://ip:admin_port/debug/pprof/heap?debug=1

这个命令其实就是把当前内存分配的详情文件抓了下来,本地会生成一个叫heap?debug=1的文件,看一看服务内存分配的具体情况:

在这里插入图片描述
有句话说的好啊:golang10次内存泄漏,8次goroutine泄漏,1次真正内存泄漏,于是我敲下了下面的命令:

$ wget http://ip:admin_port/debug/pprof/goroutine?debug=1
$ wget http://ip:admin_port/debug/pprof/goroutine?debug=2
  • debug=1就是获取服务当前goroutine的数目和大致信息
  • debug=2获取服务当前goroutine的详细信息,分别在本地生成了goroutine?debug=1和goroutine?debug=2文件,先看前者:
    在这里插入图片描述

服务当前的goroutine数也就才1033,也不至于占用那么大的内存。再看看服务线程挂的子线程有多少:

$ ps mp 3030923 -o THREAD,tid | wc -l

好像也不多,只有20多。我们再看看后者,不看不知道,一看吓一跳:
在这里插入图片描述
可以看到goroutine里面有很多chan send这种阻塞了很长时间的case,“这不就找到问题了吗?就这?嗯?就这?”,赶紧找到对应的函数,发现之前的同学写了类似这样的代码:

func RebuildImage() {  var wg sync.WaitGroup  wg.Add(3)
  // 耗时1  go func() {    // do sth    defer wg.Done()  } ()
  // 耗时2  go func() {    // do sth    defer wg.Done()  } ()
  // 耗时3  go func() {    // do sth    defer wg.Done()  } ()
  ch := make(chan struct{})
  go func () {    wg.Wait()    ch <- struct{}{}  }()
  // 接收完成或者超时  select {  case <- ch:    return  case <- time.After(time.Second * 10):    return  }}

简单来说这段代码就是开了3个goroutine处理耗时任务,最后等待三者完成或者超时失败返回,因为这里的channel在make的时候没有设置缓冲值,所以当超时的时候函数返回,此时ch没有消费者了,就一直阻塞了。看一看这里超时的监控项和内存泄漏的曲线:

在这里插入图片描述
在这里插入图片描述
时间也能对上,至此问题解决。

参考:
https://blog.csdn.net/skh2015java/article/details/102748222
https://cloud.tencent.com/developer/article/2279678

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/838050.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二叉树的性质、前中后序遍历【详细】

1. 树概念2.二叉树的概念1.2二叉树的性质 3.二叉树遍历3.2前序遍历3.2 中序遍历3.3 后序遍历 1. 树概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合&#xff0c;有二叉树&#xff0c;N叉树等等。 子树…

[CKA]考试之一个 Pod 封装多个容器

由于最新的CKA考试改版&#xff0c;不允许存储书签&#xff0c;本博客致力怎么一步步从官网把答案找到&#xff0c;如何修改把题做对&#xff0c;下面开始我们的 CKA之旅 题目为&#xff1a; Task 创建一个Pod&#xff0c;名字为kucc1&#xff0c;这个Pod包含4容器&#xff…

Python:Spider爬虫工程化入门到进阶(1)创建Scrapy爬虫项目

Python&#xff1a;Spider爬虫工程化入门到进阶系列: Python&#xff1a;Spider爬虫工程化入门到进阶&#xff08;1&#xff09;创建Scrapy爬虫项目Python&#xff1a;Spider爬虫工程化入门到进阶&#xff08;2&#xff09;使用Spider Admin Pro管理scrapy爬虫项目 本文通过简…

眼科医生推荐的台灯 护眼台灯买什么好?

我家孩子需要一个护眼灯&#xff0c;就请教了我的一个医生朋友。大家都知道医生白天对着电脑长时间的工作&#xff0c;晚上还要看书&#xff0c;查文献&#xff0c;写论文&#xff0c;选一个对眼睛友好的高质量护眼台灯对他们是刚需&#xff0c;同时又是医生&#xff0c;所以他…

网络安全(黑客)自学建议一一附学习路线

温馨提示&#xff1a;为了避免误入歧途&#xff0c;自学请优先看《网络安全法》。 下面是一些学习建议&#xff1a; 1、多请教有经验的人 切忌钻牛角尖&#xff0c;特别是刚入门的什么都不了解的情况下&#xff0c;可能你花好几天研究的一个东西&#xff0c;人10分钟就能搞定…

windows永久暂停更新

目录 1.winr,输入regedit打开注册表 2.打开注册表的这个路径: 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 右键空白地方新建QWORD值命名为:FlightSettingsMaxPauseDays 3.双击FlightSettingsMaxPauseDays,修改里面的值为100000,右边基数设置…

互联网同摄影技术结合,图片直播的优势有哪些?

互联网同摄影技术结合&#xff0c;诞生了图片直播技术&#xff0c;这是一种区别传统摄影的商业拍摄模式。但是很多人听到图片直播都是一头雾水&#xff0c;图片直播依托于互联网和摄影技术&#xff0c;实现了边拍摄、边上传、边修图、边分享&#xff0c;实时将照片上传至互联网…

深入理解机器学习与极大似然之间的联系

似然函数&#xff1a;事件A的发生含着有许多其它事件的发生。所以我就把这些其它事件发生的联合概率来作为事件A的概率&#xff0c;也就是似然函数。数据类型的不同&#xff08;离散型和连续性&#xff09;就有不同的似然函数 极大似然极大似然估计方法&#xff08;Maximum Li…

棒球1号位:棒球联盟成立棒球学院计划

棒球联盟成立棒球学院计划 1. 引言 棒球学院&#xff0c;是一个致力于培养棒球运动员的综合性机构。我们的目标是建立一个集训练、教育和娱乐于一体的体育中心&#xff0c;将孩子们带入棒球的世界&#xff0c;发掘他们的潜力&#xff0c;培养他们的团队协作精神和体育精神。 …

开源社区寻找八月创作之星!你准备好了吗~

活动页面&#xff1a;https://openlab.cosmoplat.com/createStarCampaign-202308​​​​​​卡奥斯开源社区定位打造工业互联网行业顶级开源社区生态平台&#xff0c;为开发者、企业等用户提供代码托管、技术交流/共享、硬件认证/接入、培训认证、大赛活动等服务&#xff0c;目…

【移动机器人运动规划】02 —— 基于采样的规划算法

文章目录 前言相关代码整理:相关文章&#xff1a; 基本概念概率路线图&#xff08;Probabilistic Road Map&#xff09;基本流程预处理阶段查询阶段 优缺点&#xff08;pros&cons&#xff09;一些改进算法Lazy collision-checking Rapidly-exploring Random Tree算法伪代码…

性能分析记录

4实例压测TPS浮动在200-300 1.TPS浮动200-300&#xff0c;ART浮动的可能性是10-20ms&#xff0c;链路复杂是可接受的&#xff0c;链路简单则需要分析原因。 1&#xff09;缓存没命中&#xff0c;对某些账号缓存没命中&#xff0c;或缓存失效后导致隔段时间耗时升高。 2&…

机器学习入门之 pandas

pandas 有三种数据结构 一种是 Series 一种是 Dataframe import pandas as pd import numpy as np score np.random.randint(0,100,[10,5])score[0,0] 100Datascore pd.DataFrame(score)subject ["语文","数学","英语","物理&quo…

孙哥撕毁协议侵占“火币”商标,在港吃官司胜算几何?

李林与孙哥的“火币”使用权之争正在进入新的法律阶段&#xff1a;消息人士透露&#xff0c;X-Spot有限公司&#xff08;实控人李林&#xff09;起诉火必-Huobi Global Limited&#xff08;实控人孙宇晨&#xff09;违反合同约定侵权使用中文‘火币’、‘火幣’商标一案&#x…

【redis】能ping通虚拟机但是端口无法访问

问题 虚拟机上有redis&#xff0c;能ping通虚拟机的ip&#xff0c;但是idea连不上虚拟机里的redis&#xff0c;telnet已启动的redis6379端口失败 基本情况 虚拟机网络模式是NAT模式&#xff0c;linux防火墙firewalld已关闭&#xff0c;没有iptables&#xff0c;主机和虚拟机…

东南亚跨境电商必看,使用代理IP洞察市场先机-IPIDEA全球HTTP

东南亚连续第三年成为全球电子商务增长最快的地区&#xff0c;预计到2025年&#xff0c;东南亚电商的市场规模将会达到2,340亿美元。虽然起步较晚&#xff0c;但随着移动互联网和数字支付的普及&#xff0c;东南亚跨境市场迅速崛起&#xff0c;呈现出蓬勃的发展态势。 人口基数…

Consul屏蔽api

consul 没有设置密码 需要屏蔽api&#xff1a;/v1/internal/ui/nodes?dc&token 防止信息泄露 配置config.json {"http_config": {"block_endpoints": ["/v1/internal/ui/nodes"]} }启动consul时使用该配置&#xff1a; consul agent -de…

模块化原理:source-map

1. webpack打包基本配置 1.安装webpack与webpack-cli npm i webpack webpack-cli 2.配置 "build":"webpack" 3. 新建webpack.config.js const path require(path); module.exports {// mode: "development",// 默认production&#xff08;什么…

2023年土木、建筑与环境工程国际会议(ICCAEE 2023) | EI Compendex, Scopus双检索

会议简介 Brief Introduction 2023年土木、建筑与环境工程国际会议(ICCAEE 2023) 会议时间&#xff1a;2023年11月17日-19日 召开地点&#xff1a;中国广州 大会官网&#xff1a;ICCAEE 2023-2023 International Conference on Civil, Architectural and Environmental Enginee…

常见的设计模式(超详细)

文章目录 单例模式饿汉式单例模式懒汉式单例模式双重检索单例模式 工厂模式简单工厂模式工厂&#xff08;方法&#xff09;模式抽象工厂模式 原型模式代理模式 单例模式 确保一个类只有一个实例&#xff0c;并且自行实例化并向整个系统提供这个实例。 饿汉式单例模式 饿汉式单…