Go语言pprof实战笔记(中) | 青训营

前言

上期我们简单做了一个排查CPU占用过高的实践,相信小伙伴们已经熟悉了go tool pprof这个工具了,这期我们实验的节奏会更快,要做好几个实验哦

实战开始

老规矩,先把 炸弹程序 运行起来,然后打开任务管理器观察有哪些异常的性能数据。

排查内存占用过高

我们很明显地看到这个程序的占用了 7GB 多的内存,实在是太恐怖啦。

我们要排查的是内存占用过高,理所当然的应该借助 go tool pprof命令来分析 heap 文件。接下来,准备动手,打开命令行输入go tool pprof http://localhost:6060/debug/pprof/heap。很快啊,熟悉的交互式终端就出现了。

首先使用top命令查看到底是哪些方法占用了这么多内存

经过一番仔细的查看,发现原来是
github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Pee.func1方法和github.com/wolfogre/go-pprof-practice/animal/muridae/mouse.(*Mouse).Steal方法各自占用了 1.2GB 的内存。

有两处地方都有问题,我们先使用list命令查看Pee方法有什么问题

原来是在Pee方法里面启动了一个goroutine来不断地往一个名叫slowBuffer的二维切片里面追加一维切片。好了,问题找到了,接下来使用list命令查看Steal方法有什么问题。

定睛一看,原来是一样的问题,那么我们先把这两个地方 优化(注释) 掉。

此处省略优化的详细步骤...

在优化后重新启动程序,可以发现 CPU内存 看起来都很正常,没有出现异常的数据,那么问题真的就没有了吗?

排查频繁GC

GC 的全称是 Garbage Collection,翻译过来为垃圾回收,用在计算机领域就被称为内存回收。这是一种自动内存管理的机制,它会自动回收那些被分配但不再被使用的内存。这种机制可以帮助开发者避免很多常见的内存管理错误,例如内存泄漏和野指针等问题。

大家都知道golang是追求高性能的,那么频繁的 GC 肯定会影响程序的性能,这是golang所不允许的。虽然现在 CPU内存 的使用率都没有问题,但是我们还是要排查 GC 的回收情况。

所以我们接下来的排查不是排查哪里占用了大量的内存,而是排查哪里在频繁地申请内存又不用,触发GC,影响程序性能。

正常情况来说,我们是不知道 GC 的情况的,那么我们如何来了解 GC 是否频繁发生呢?答案就是查看 GC 日志。为了能查看 GC 的日志,我们需要设置环境变量set GODEBUG=gctrace=1,这样设置的环境变量只在当前终端窗口有效,能有效防止影响到其他 GO 程序的输出。

接下来在终端输入go-pprof-practice.exe | findstr gc,运行 GO 程序的同时把日志做一次过滤,能有效屏蔽其他日志对我们的干扰。

通过 GC 日志我们发现 GC 差不多每3秒就要发生一次,每次都是申请了16MB 的空间然后被 GC 回收掉了,所以大概率是某个地方申请了16MB 空间然后没有使用,被 GC 回收掉了。

对于问题有了自己初步的判断,接下来就是使用go tool pprof命令来检查实际的问题了。还是原来的步骤,使用top list命令来排查相关的问题,不过这里有个前提,就是需要等待程序运行一会,因为内存的分配和回收的频率都是需要一段时间来统计的。

等待程序运行一段时间后输入go tool pprof http://localhost:6060/debug/pprof/allocs进入交互式终端,然后输入top命令查看内存分配情况

可以看到github.com/wolfogre/go-pprof-practice/animal/canidae/dog.(*Dog).Run方法存在问题,接下来使用list命令查看有问题的代码具体在哪。

我们可以看到在Run方法里面存在这样一行代码_ = make([]byte, 16*constant.Mi),这行代码分配了16MB 内存,但是使用了匿名变量 来忽略返回值,导致这个内存没有被使用,没在使用的空间自然就需要 GC 来回收了。

老规矩,发现问题后注释掉(练习需要,切勿模仿

重新启动后观察一下 GC 日志。很好,没有问题了。

总结

目前用到的命令其实很少也很简单,只需要我们有一双善于发现问题的眼睛,就能使用工具快速定位问题。

好了,还剩几个实践操作我们下期见!

相关推荐
夭要7夜宵4 天前
Go 垃圾回收 | 豆包MarsCode AI刷题
青训营笔记
末班车4224 天前
前端框架中的设计模式 | 豆包MarsCode AI刷题
青训营笔记
VanceLLF5 天前
神奇数字组合 | 豆包MarsCode AI刷题
青训营笔记
lann5 天前
Go 程序的优化 | 豆包MarsCode AI刷题
青训营笔记
用户52281271049785 天前
性能优化与调试技巧 | 豆包MarsCode AI刷题
青训营笔记
千慌百风定乾坤7 天前
Go 语言入门指南:基础语法和常用特性解析(下) | 豆包MarsCode AI刷题
青训营笔记
FOFO7 天前
青训营笔记 | HTML语义化的案例分析: 粗略地手绘分析juejin.cn首页 | 豆包MarsCode AI 刷题
青训营笔记
滑滑滑9 天前
后端实践-优化一个已有的 Go 程序提高其性能 | 豆包MarsCode AI刷题
青训营笔记
柠檬柠檬9 天前
Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题
青训营笔记
用户967136399659 天前
计算最小步长丨豆包MarsCodeAI刷题
青训营笔记