当前位置: 首页 > news >正文

常用调试golang的bug以及性能问题的实践方法

文章目录

  • 如何分析程序运行时间和CPU利用率情况
    • 1.shell内置time指令
    • /usr/bin/time指令
  • 如何分析golang程序的内存使用情况?
    • 1.内存占用情况查看
  • 如何分析golang程序的CPU性能情况
    • 1.性能分析注意事项
    • 2.CPU性能分析
      • A.Web界面查看
      • B.使用pprof工具查看

如何分析程序运行时间和CPU利用率情况

1.shell内置time指令

time是Unix/linux内置多命令,使用时一般不用传过多参数,直接跟上需要调试多程序即可。

$ time go run test2.go 
&{{0 0} 张三 0}real	0m0.843s
user	0m0.216s
sys	0m0.389s

上面是使用time对 go run test2.go对执行程序坐了性能分析,得到3个指标。

● real:从程序开始到结束,实际度过的时间;
● user:程序在用户态度过的时间;
● sys:程序在内核态度过的时间。

一般情况下 real >= user + sys,因为系统还有其它进程(切换其他进程中间对于本进程会有空白期)

/usr/bin/time指令

这个指令比内置的time更加详细一些,使用的时候需要用绝对路径,而且要加上参数-v

$ /usr/bin/time -v go run test2.go  Command being timed: "go run test2.go"User time (seconds): 0.12System time (seconds): 0.06Percent of CPU this job got: 115%Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.16Average shared text size (kbytes): 0Average unshared data size (kbytes): 0Average stack size (kbytes): 0Average total size (kbytes): 0Maximum resident set size (kbytes): 41172Average resident set size (kbytes): 0Major (requiring I/O) page faults: 1Minor (reclaiming a frame) page faults: 15880Voluntary context switches: 897Involuntary context switches: 183Swaps: 0File system inputs: 256File system outputs: 2664Socket messages sent: 0Socket messages received: 0Signals delivered: 0Page size (bytes): 4096Exit status: 0

可以看到这里的功能要强大多了,除了之前的信息外,还包括了:

● CPU占用率;
● 内存使用情况;
● Page Fault 情况;
● 进程切换情况;
● 文件系统IO;
● Socket 使用情况;
● ……

如何分析golang程序的内存使用情况?

1.内存占用情况查看

package mainimport ("log""runtime""time"
)func test() {//slice 会动态扩容,用slice来做堆内存申请container := make([]int, 8)log.Println(" ===> loop begin.")for i := 0; i < 32*1000*1000; i++ {container = append(container, i)}log.Println(" ===> loop end.")
}func main() {log.Println("Start.")test()log.Println("force gc.")runtime.GC() //强制调用gc回收log.Println("Done.")time.Sleep(3600 * time.Second) //睡眠,保持程序不退出
}

编译

$go build -o snippet && ./snippet

然后在./snippet进程没有执行完,我们再开一个窗口,通过top命令查看进程的内存占用情况

$top -p $(pidof snippet_mem)

结果如下:
在这里插入图片描述
我们看出来,没有退出的snippet_mem进程有约830m的内存被占用。

直观上来说,这个程序在test()函数执行完后,切片contaner的内存应该被释放,不应该占用830M那么大。
结论:
1、在test()函数执行完后,demo程序中的切片容器所申请的堆空间都被垃圾回收器回收了。

2、如果此时在top指令查询内存的时候,如果依然是800+MB,说明垃圾回收器回收了应用层的内存后,(可能)并不会立即将内存归还给系统。

如何分析golang程序的CPU性能情况

1.性能分析注意事项

● 性能分析必须在一个
可重复的、稳定的环境中来进行。
○ 机器必须闲置
■ 不要在共享硬件上进行性能分析;
■ 不要在性能分析期间,在同一个机器上去浏览网页
○ 注意省电模式和过热保护,如果突然进入这些模式,会导致分析数据严重不准确
○ 不要使用虚拟机、共享的云主机,太多干扰因素,分析数据会很不一致;
○ 不要在 macOS 10.11 及以前的版本运行性能分析,有 bug,之后的版本修复了。

如果承受得起,购买专用的性能测试分析的硬件设备,上架。

● 关闭电源管理、过热管理;
● 绝不要升级,以保证测试的一致性,以及具有可比性。

如果没有这样的环境,那就一定要在多个环境中,执行多次,以取得可参考的、具有相对一致性的测试结果

2.CPU性能分析

利用以下代码进行测试:

package mainimport ("bytes""math/rand""time""log""net/http"_ "net/http/pprof"
)func test() {log.Println(" ===> loop begin.")for i := 0; i < 1000; i++ {log.Println(genSomeBytes())}log.Println(" ===> loop end.")
}//生成一个随机字符串
func genSomeBytes() *bytes.Buffer {var buff bytes.Bufferfor i := 1; i < 20000; i++ {buff.Write([]byte{'0' + byte(rand.Intn(10))})}return &buff
}func main() {go func() {for {test()time.Sleep(time.Second * 1)}}()//启动pprofhttp.ListenAndServe("0.0.0.0:10000", nil)}

这里面还是启动了pprof的监听,有关pprof启动的代码如下:

import ("net/http"_ "net/http/pprof"
)func main() {//...//...//启动pprofhttp.ListenAndServe("0.0.0.0:10000", nil)
}

main()里的流程很简单,启动一个goroutine去无限循环调用test()方法,休眠1s.

test()的流程是生成1000个20000个字符的随机字符串.并且打印.

我们将上面的代码编译成可执行的二进制文件 demo4(记住这个名字,稍后我们能用到)

$ go build demo4.go

接下来我们启动程序,程序会无限循环的打印字符串.

接下来我们通过几种方式来查看进程的cpu性能情况.

A.Web界面查看

浏览器访问http://127.0.0.1:10000/debug/pprof/

我们会看到如下画面
在这里插入图片描述
这里面能够通过pprof查看包括(阻塞信息、cpu信息、内存堆信息、锁信息、goroutine信息等等), 我们这里关心的cpu的性能的profile信息.

有关profile下面的英文解释大致如下:

“CPU配置文件。您可以在秒GET参数中指定持续时间。获取概要文件后,请使用go tool pprof命令调查概要文件。”

所以我们要是想得到cpu性能,就是要获取到当前进程的profile文件,这个文件默认是30s生成一个,所以你的程序要至少运行30s以上(这个参数也可以修改,稍后我们介绍)

我们可以直接点击网页的profile,浏览器会给我们下载一个profile文件. 记住这个文件的路径, 可以拷贝到与demo4所在的同一文件夹下.

B.使用pprof工具查看

pprof 的格式如下:

go tool pprof [binary] [profile]

binary: 必须指向生成这个性能分析数据的那个二进制可执行文件;

profile: 必须是该二进制可执行文件所生成的性能分析数据文件。

binary 和 profile 必须严格匹配。

我们来查看一下:

$ go tool pprof ./demo4 profileFile: demo4
Type: cpu
Time: Mar 3, 2020 at 11:18pm (CST)
Duration: 30.13s, Total samples = 6.27s (20.81%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof)

help可以查看一些指令,我么可以通过top来查看cpu的性能情况.

(pprof) top
Showing nodes accounting for 5090ms, 81.18% of 6270ms total
Dropped 80 nodes (cum <= 31.35ms)
Showing top 10 nodes out of 60flat  flat%   sum%        cum   cum%1060ms 16.91% 16.91%     2170ms 34.61%  math/rand.(*lockedSource).Int63850ms 13.56% 30.46%      850ms 13.56%  sync.(*Mutex).Unlock (inline)710ms 11.32% 41.79%     2950ms 47.05%  math/rand.(*Rand).Int31n570ms  9.09% 50.88%      990ms 15.79%  bytes.(*Buffer).Write530ms  8.45% 59.33%      540ms  8.61%  syscall.Syscall370ms  5.90% 65.23%      370ms  5.90%  runtime.procyield270ms  4.31% 69.54%     4490ms 71.61%  main.genSomeBytes250ms  3.99% 73.52%     3200ms 51.04%  math/rand.(*Rand).Intn250ms  3.99% 77.51%      250ms  3.99%  runtime.memmove230ms  3.67% 81.18%      690ms 11.00%  runtime.suspendG
(pprof)

这里面有几列数据,需要说明一下.

● flat:当前函数占用CPU的耗时
● flat%::当前函数占用CPU的耗时百分比
● sum%:函数占用CPU的耗时累计百分比
● cum:当前函数加上调用当前函数的函数占用CPU的总耗时
● cum%:当前函数加上调用当前函数的函数占用CPU的总耗时百分比
● 最后一列:函数名称

通过结果我们可以看出, 该程序的大部分cpu性能消耗在 main.getSoneBytes()方法中,其中math/rand取随机数消耗比较大.

相关文章:

常用调试golang的bug以及性能问题的实践方法

文章目录如何分析程序运行时间和CPU利用率情况1.shell内置time指令/usr/bin/time指令如何分析golang程序的内存使用情况&#xff1f;1.内存占用情况查看如何分析golang程序的CPU性能情况1.性能分析注意事项2.CPU性能分析A.Web界面查看B.使用pprof工具查看如何分析程序运行时间和…...

什么是溶血症?什么是ABO溶血?溶血检查些什么?

什么是溶血症&#xff0c;什么是ABO溶血&#xff1f;女人是O型血&#xff0c;男人是其他血型的夫妻配对&#xff0c;最担心的是胎儿溶血症。从理论上讲&#xff0c;只要夫妻双方血型不同&#xff0c;母亲一定缺乏胎儿从父亲那里遗传的抗原。当任何人接触到他们缺乏的抗原时&…...

NLP实践——知识图谱问答模型FiD

NLP实践——知识图谱问答模型FiD0. 简介1. 模型结构2. 召回3. 问答4. 结合知识的问答0. 简介 好久没有更新了&#xff0c;今天介绍一个知识图谱问答&#xff08;KBQA&#xff09;模型&#xff0c;在此之前我一直在用huggingface的Pipeline中提供的QA模型&#xff0c;非常方便但…...

MyBatis 多表关联查询

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

《NFL橄榄球》:克利夫兰布朗·橄榄1号位

克利夫兰布朗&#xff08;英语&#xff1a;Cleveland Browns&#xff09;是一支职业美式橄榄球球队&#xff0c;位于俄亥俄州克利夫兰。 布朗隶属于美国全国橄榄球联盟(NFL)的北区&#xff0c;主场位于第一能源体育场。球队在1946年与AAFC联盟一同成立&#xff0c;并在1946年到…...

InstructGPT笔记

一、InstructGPT是在GPT3上微调&#xff0c;ChatGPT是在GPT3.5上微调 二、该论文展示了怎么样对语言模型和人类意图之间进行匹配&#xff0c;方法是在人类的反馈上进行微调。 **三、方法简介&#xff1a;**收集很多问题&#xff0c;使用标注工具将问题的答案写出来&#xff0…...

【uniapp】getOpenerEventChannel().once 接收参数无效的解决方案

uniapp项目开发跨平台应用常会遇到接收参数无效的问题&#xff0c;无法判断是哪里出错了&#xff0c;这里是讲替代的方案&#xff0c;现有三种方案可选。 原因 一般我们是这样处理向另一个页面传参&#xff0c;代码是这样写的 //... let { title, type, rank } args; uni.n…...

ELK分布式日志收集快速入门-(二)kafka进阶-快速安装可视化管理界面-(单节点部署)

目录安装前准备安装中安装成功安装前准备 安装kafka-参考博客 (10条消息) ELK分布式日志收集快速入门-&#xff08;一&#xff09;-kafka单体篇_康世行的博客-CSDN博客 安装zk 参考博客 (10条消息) 快速搭建-分布式远程调用框架搭建-dubbozookperspringboot demo 演示_康世行的…...

线程的创建

1. 多线程常用函数 1.1 创建一条新线程pthread_create 对此函数使用注意以下几点&#xff1a; 线程例程指的是&#xff1a;如果线程创建成功&#xff0c;则该线程会立即执行的函数。POSIX线程库的所有API对返回值的处理原则一致&#xff1a;成功返回0&#xff0c;失败返回错误…...

分布式之Paxos共识算法分析

写在前面 分布式共识是分布式系统中的重要内容&#xff0c;本文来一起看下&#xff0c;一种历史悠久&#xff08;1998由兰伯特提出&#xff0c;并助其获得2003年图灵奖&#xff09;的实现分布式共识的算法Paxos。Paxos主要分为两部分&#xff0c;Basic Paxos和Multi-Paxos,其中…...

35岁测试工程师,面临中年危机,我该如何自救...

被辞的原因 最近因故来了上海&#xff0c;联系上了一位许久不见的老朋友&#xff0c;老王&#xff1b;老王和我是大学同学&#xff0c;毕业之后他去了上海&#xff0c;我来到广州。因为我们大学专业关系&#xff0c;从12年毕业以后我们从事着相同的职业&#xff0c;软件自动化…...

时间轮算法概念

概述 在一些中间件中我们经常见到时间轮控制并发和熔断。 那么这个时间轮具体是什么呢&#xff0c;又是怎么使用的呢。 简介 其实时间轮可以简单的理解成我们日常生活中的时钟。 时钟里的指针一直在不停的转动&#xff0c;利用这个我们可以实现定时任务&#xff0c;目前lin…...

[SCTF2019]babyre 题解

对未来的真正慷慨&#xff0c;是把一切献给现在。 ——加缪 目录 1.查壳 2.处理花指令&#xff0c;找到main函数 这一操作过程可以参考下面的视频&#xff1a; 3.静态分析第一部分,psword1 4.静态分析第二部分,psword2 5.静态分析第五部分&#xff0c;psword3 6.根据ps…...

全志H3系统移植 | 移植主线最新uboot 2023.04和kernel 6.1.11到Nanopi NEO开发板

文章目录 环境说明uboot移植kernel移植rootfs移植测试环境说明 OS:Ubuntu 20.04.5 LTSGCC:arm-none-linux-gnueabihf-gcc 10.3.0编译器下载地址:Downloads | GNU-A Downloads – Arm Developer uboot移植 当前最新版本v2023.04-rc2下载地址:https://github.com/u-boot/u-…...

vue项目第四天

使用elementui tabplane组件实现历史访问记录组件的二次封装<el-tabs type"border-card"><el-tab-pane label"用户管理">用户管理</el-tab-pane><el-tab-pane label"配置管理">配置管理</el-tab-pane><el-tab-…...

「C语言进阶」数据内存的存储

&#x1f680;&#x1f680;&#x1f680;大家觉不错的话&#xff0c;就恳求大家点点关注&#xff0c;点点小爱心&#xff0c;指点指点&#x1f680;&#x1f680;&#x1f680; 目录 &#x1f430;数据类型的介绍 &#x1f430;类型的意义 &#x1f430;数据类型的基本归类…...

面试必问:进程和线程的区别(从操作系统层次理解)

1.什么是进程&#xff1f;为什么要有进程&#xff1f; 进程有一个相当精简的解释&#xff1a;进程是对操作系统上正在运行程序的一个抽象。 这个概念确实挺抽象&#xff0c;仔细想想却也挺精准。 我们平常使用计算机&#xff0c;都会在同一时间做许多事&#xff0c;比如边看…...

ModuleNotFoundError: No module named ‘apex‘与 error: legacy-install-failure

ModuleNotFoundError: No module named ‘apex’ ModuleNotFoundError: No module named apex 表示 Python 在搜索模块时无法找到名为 apex 的模块。这通常是因为您没有安装 apex 模块或安装不正确。 apex 是一个针对混合精度训练和优化的 PyTorch 扩展库&#xff0c;您可以通过…...

Python3 VScode 配置

Python3 VScode 配置 在上一章节中我们已经安装了 Python 的环境&#xff0c;本章节我们将介绍 Python VScode 的配置。 准备工作&#xff1a; 安装 VS Code 安装 VS Code Python 扩展 安装 Python 3 安装 VS Code VSCode&#xff08;全称&#xff1a;Visual Studio Code&…...

VMware 修复了三个身份认证绕过漏洞

Bleeping Computer 网站披露&#xff0c;VMware 近期发布了安全更新&#xff0c;以解决 Workspace ONE Assist 解决方案中的三个严重漏洞&#xff0c;分别追踪为 CVE-2022-31685&#xff08;认证绕过&#xff09;、CVE-2022-31686 &#xff08;认证方法失败&#xff09;和 CVE-…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...