【go】pprof 性能分析

news2024/11/23 15:16:25

前言

go pprof是 Go 语言提供的性能分析工具。它可以帮助开发者分析 Go 程序的性能问题,包括 CPU 使用情况、内存分配情况、阻塞情况等。

主要功能

CPU 性能分析

go pprof可以对程序的 CPU 使用情况进行分析。它通过在一定时间内对程序的执行进行采样,记录每个函数被调用的次数和执行时间。通过分析这些采样数据,可以确定程序中哪些函数占用了较多的 CPU 时间,从而帮助开发者找到性能瓶颈并进行优化。

例如,使用go tool pprof命令加上程序的 CPU 性能分析文件,可以启动一个交互式的分析界面。在这个界面中,可以使用各种命令查看不同函数的 CPU 使用情况,如top命令可以显示占用 CPU 时间最多的函数列表。

内存性能分析

这个工具可以分析程序的内存分配情况。它可以记录程序在运行过程中每个函数分配的内存大小和数量。通过分析这些数据,可以确定程序中哪些函数可能存在内存泄漏或过度分配内存的问题。

例如,使用go tool pprof命令加上程序的内存性能分析文件,可以查看内存分配的情况。可以使用list命令查看特定函数的内存分配情况,或者使用web命令生成一个可视化的内存分配报告。

阻塞分析

go pprof还可以分析程序中的阻塞情况。它可以检测程序在哪些地方出现了阻塞,如等待锁、通道通信或系统调用等。通过分析阻塞情况,可以帮助开发者找到程序中的并发问题并进行优化。

例如,使用go tool pprof命令加上程序的阻塞分析文件,可以查看程序中的阻塞情况。可以使用top命令查看最常见的阻塞点,或者使用list命令查看特定函数的阻塞情况。

优势

易于使用

go pprof是 Go 语言内置的工具,无需安装额外的软件即可使用。它的使用方法相对简单,只需要在程序中添加几行代码就可以生成性能分析文件,然后使用go tool pprof命令进行分析。

强大的分析功能

go pprof提供了丰富的分析功能,可以分析程序的 CPU 使用情况、内存分配情况、阻塞情况等。它还可以生成可视化的报告,帮助开发者更直观地了解程序的性能问题。

与 Go 语言紧密集成

由于go pprof是 Go 语言内置的工具,它与 Go 语言的其他工具和库紧密集成。例如,可以使用go test命令结合-cpuprofile-memprofile参数来生成性能分析文件,方便在测试过程中进行性能分析。

CPU profiling

pprof 使用非常简单。首先调用pprof.StartCPUProfile()启用 CPU profiling。它接受一个io.Writer类型的参数,pprof会将分析结果写入这个io.Writer中。为了方便事后分析,我们写到一个文件中。

在要分析的代码后调用pprof.StopCPUProfile()。那么StartCPUProfile()StopCPUProfile()之间的代码执行情况都会被分析。方便起见可以直接在StartCPUProfile()后,用defer调用StopCPUProfile(),即分析这之后的所有代码。

来个普通的demo,后面内存分析也用这段代码

import (
	"math/rand"
	"os"
	"runtime/pprof"
	"strings"
	"time"
)

func generate(n int) []int {
	nums := make([]int, 0)
	for i := 0; i < n; i++ {
		nums = append(nums, rand.Int())
	}
	return nums
}

func bubbleSort(nums []int) {
	for i := 0; i < len(nums); i++ {
		for j := 1; j < len(nums)-i; j++ {
			if nums[j] < nums[j-1] {
				nums[j], nums[j-1] = nums[j-1], nums[j]
			}
		}
	}
}

type A struct {
	b *B
}

type B struct {
	c *C
}

type C struct {
}

func (a *A) func_a() {
	a.b.func_b()
}

func (b *B) func_b() {
	b.c.func_c()
}

func (c *C) func_c() {
	nums := generate(10000)
	bubbleSort(nums)
}

使用 pprof 分析一下运行情况

func main() {
    f, _ := os.OpenFile("cpu.pprof", os.O_CREATE|os.O_RDWR, 0644)
    defer f.Close()
    pprof.StartCPUProfile(f)
    defer pprof.StopCPUProfile()

    a := &A{
            b: &B{
                    c: &C{},
            },
    }
    a.func_a()

    time.Sleep(time.Second)
}

执行go run main.go,会生成一个cpu.pprof文件。这个文件记录了程序的运行状态。使用go tool pprof命令分析这个文件:

>> go tool pprof cpu.pprof            
File: pprof2
Type: cpu
Time: Sep 11, 2024 at 5:40pm (CST)
Duration: 202.37ms, Total samples = 70ms (34.59%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 70ms, 100% of 70ms total
      flat  flat%   sum%        cum   cum%
      70ms   100%   100%       70ms   100%  main.bubbleSort (inline)
         0     0%   100%       70ms   100%  main.(*A).func_a (inline)
         0     0%   100%       70ms   100%  main.(*B).func_b (inline)
         0     0%   100%       70ms   100%  main.(*C).func_c
         0     0%   100%       70ms   100%  main.main
         0     0%   100%       70ms   100%  runtime.main
(pprof) 

list 分析

上面用top命令查看耗时最高的 10 个函数。可以看到bubbleSort函数耗时最高,累计耗时 70ms,占了总耗时的 100%。我们也可以使用top 5top 20分别查看耗时最高的 5 个 和 20 个函数。

当找到耗时较多的函数,我们还可以使用list命令查看该函数是怎么被调用的,各个调用路径上的耗时是怎样的。list命令后跟一个表示方法名的模式:

(pprof) list bubbleSort
Total: 50ms
ROUTINE ======================== main.bubbleSort in /Users/jasper/work/gitee/test-go/src/pprof/pprof2.go
      50ms       50ms (flat, cum)   100% of Total
         .          .     58:   return nums
         .          .     59:}
      10ms       10ms     60:func bubbleSort(nums []int) {
      40ms       40ms     61:   for i := 0; i < len(nums); i++ {
         .          .     62:           for j := 1; j < len(nums)-i; j++ {
         .          .     63:                   if nums[j] < nums[j-1] {
         .          .     64:                           nums[j], nums[j-1] = nums[j-1], nums[j]
         .          .     65:                   }
         .          .     66:           }
(pprof) %                                                

help 查看所有的命令

(pprof) help
  Commands:
    callgrind        Outputs a graph in callgrind format
    comments         Output all profile comments
    disasm           Output assembly listings annotated with samples
    dot              Outputs a graph in DOT format
    eog              Visualize graph through eog
    evince           Visualize graph through evince
    gif              Outputs a graph image in GIF format
    gv               Visualize graph through gv
    kcachegrind      Visualize report in KCachegrind
    list             Output annotated source for functions matching regexp
    pdf              Outputs a graph in PDF format
    peek             Output callers/callees of functions matching regexp
    png              Outputs a graph image in PNG format
    proto            Outputs the profile in compressed protobuf format
    ps               Outputs a graph in PS format
    raw              Outputs a text representation of the raw profile
    svg              Outputs a graph in SVG format
    tags             Outputs all tags in the profile
    text             Outputs top entries in text form
    top              Outputs top entries in text form
    topproto         Outputs top entries in compressed protobuf format
    traces           Outputs all profile samples in text form
    tree             Outputs a text rendering of call graph
    web              Visualize graph through web browser
    weblist          Display annotated source in a web browser
    o/options        List options and their current values
    q/quit/exit/^D   Exit pprof

  Options:
    call_tree        Create a context-sensitive call tree
    compact_labels   Show minimal headers
    divide_by        Ratio to divide all samples before visualization
    drop_negative    Ignore negative differences
    edgefraction     Hide edges below <f>*total
    focus            Restricts to samples going through a node matching regexp
    hide             Skips nodes matching regexp
    ignore           Skips paths going through any nodes matching regexp
    intel_syntax     Show assembly in Intel syntax
    mean             Average sample value over first value (count)
    nodecount        Max number of nodes to show
    nodefraction     Hide nodes below <f>*total
    noinlines        Ignore inlines.
    normalize        Scales profile based on the base profile.
    output           Output filename for file-based outputs
    prune_from       Drops any functions below the matched frame.
    relative_percentages Show percentages relative to focused subgraph
    sample_index     Sample value to report (0-based index or name)
    show             Only show nodes matching regexp
    show_from        Drops functions above the highest matched frame.
    source_path      Search path for source files
    tagfocus         Restricts to samples with tags in range or matched by regexp
    taghide          Skip tags matching this regexp
    tagignore        Discard samples with tags in range or matched by regexp
    tagleaf          Adds pseudo stack frames for labels key/value pairs at the callstack leaf.
    tagroot          Adds pseudo stack frames for labels key/value pairs at the callstack root.
    tagshow          Only consider tags matching this regexp
    trim             Honor nodefraction/edgefraction/nodecount defaults
    trim_path        Path to trim from source paths before search
    unit             Measurement units to display

  Option groups (only set one per group):
    granularity      
      functions        Aggregate at the function level.
      filefunctions    Aggregate at the function level.
      files            Aggregate at the file level.
      lines            Aggregate at the source code line level.
      addresses        Aggregate at the address level.
    sort             
      cum              Sort entries based on cumulative weight
      flat             Sort entries based on own weight
  :   Clear focus/ignore/hide/tagfocus/tagignore

  type "help <cmd|option>" for more information
(pprof) 

web 模式查看

在浏览器中分析CPU性能数据

go tool pprof -http=:8081 cpu.pprof

image

火焰图
image

Memory profiling

上面的CPU分析,内容换成字符串拼接

func (c *C) func_c() {
	concat(30000)
}

const letterBytes = "abcdefghijklmnopqrstuvwxyz"

func randomString(n int) string {
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	return string(b)
}

func concat(n int) string {
    var s = ""
	for i := 0; i < n; i++ {
		s += randomString(100)
	}
	return s
}

func main() {
	f, _ := os.OpenFile("mem.pprof", os.O_CREATE|os.O_RDWR, 0644)
	defer f.Close()

	a := &A{
		b: &B{
			c: &C{},
		},
	}
	a.func_a()

	pprof.WriteHeapProfile(f)

	time.Sleep(time.Second)
}

分析

分析的过程,与上面的CPU部分类似

>> go tool pprof mem.pprof
File: pprof2
Type: inuse_space
Time: Sep 11, 2024 at 5:55pm (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top 
Showing nodes accounting for 674.18kB, 100% of 674.18kB total
      flat  flat%   sum%        cum   cum%
  674.18kB   100%   100%   674.18kB   100%  main.concat
         0     0%   100%   674.18kB   100%  main.(*A).func_a (inline)
         0     0%   100%   674.18kB   100%  main.(*B).func_b (inline)
         0     0%   100%   674.18kB   100%  main.(*C).func_c (inline)
         0     0%   100%   674.18kB   100%  main.main
         0     0%   100%   674.18kB   100%  runtime.main
(pprof) list concat
Total: 674.18kB
ROUTINE ======================== main.concat in /Users/jasper/work/gitee/test-go/src/pprof/pprof2.go
  674.18kB   674.18kB (flat, cum)   100% of Total
         .          .     46:func concat(n int) string {
         .          .     47:   var s = ""
         .          .     48:   for i := 0; i < n; i++ {
  674.18kB   674.18kB     49:           s += randomString(100)
         .          .     50:   }
         .          .     51:   return s
         .          .     52:}
         .          .     53:
         .          .     54:func generate(n int) []int {
(pprof) 

+做字符串拼接是很耗内存的,各位可以试着用strings.Builder,然后观察内存占用的变化。

web 模式查看

在浏览器中分析CPU性能数据

go tool pprof -http=:8081 mem.pprof

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

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

相关文章

17个常见的电子邮件营销错误及避免方法

我们都在邮件营销中犯过错误。你点击发送&#xff0c;然后感到一阵沉重的感觉。你搞砸了&#xff0c;现在全世界都能看到你的错误。这就像把一封信放在瓶子里扔进无边的互联网海洋&#xff0c;你无法把它收回来。 有些邮件营销错误显而易见&#xff0c;可能会让你所有的努力化…

Redis学习Day3——项目工程开发`

扩展阅读推荐&#xff1a; 黑马程序员Redis入门到实战教程_哔哩哔哩_bilibili 使用git命令行将本地仓库代码上传到gitee/github远程仓库-CSDN博客 一、项目介绍及其初始化 学习Redis的过程&#xff0c;我们还将遇到各种实际问题&#xff0c;例如缓存击穿、雪崩、热Key等问题&…

想将桌面移动到D盘,但是不小心将D盘整个改成桌面的快捷方式了的解决办法

本帖为经验分享&#xff0c;因而附带了解释。 着急的uu请直接按照红色&#xff08;蓝色&#xff09;加粗标号直接操作&#xff01; 目录 一、问题描述 二、问题出现的原因 三、解决方法 一、问题描述 想将桌面移动到D盘&#xff0c;但是不小心将D盘整个改成桌面的快捷方式。…

老旧电力系统安全隐患增加 该如何预防电气线路老化等因素引发的电气火灾呢?

为应对我国电气火灾事故频发的挑战&#xff0c;安科瑞电气股份有限公司开发了AcrelCloud-6000安全用电管理云平台。这一平台依托移动互联网和云计算技术&#xff0c;结合物联网传感器&#xff0c;将办公楼、学校、医院、工厂、体育场馆、宾馆及福利院等人员密集场所的电气安全数…

爬虫--基于python的旅游网站数据分析与可视化实现---附源码78517

摘要 在数字化时代&#xff0c;旅游网站积累了大量用户数据&#xff0c;这些数据中蕴藏着丰富的信息和价值。为了更好地理解用户行为、优化旅游服务体验和提高业务运营效率&#xff0c;对旅游网站数据进行深度挖掘和可视化展示显得尤为重要。本文借助Python编程语言&#xff0c…

前端Excel热成像数据展示及插值算法

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏:《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 目录 &#x1f4d8; 前言 &#x1f4d8;一、热成像数…

最受欢迎的10款电脑监控软件大揭秘,员工电脑监控软件真心推荐

随着科技的迅猛发展&#xff0c;越来越多的企业和个人开始关注电脑监控软件的使用。这类软件能够帮助企业管理者更好地了解员工的工作状况&#xff0c;提升工作效率&#xff0c;并确保公司数据安全&#xff1b;个人用户也可以利用这些软件监控电脑活动&#xff0c;保护家人尤其…

电源自动测试系统有哪些原理和优势?

‌电源自动测试系统是一种自动测试设备&#xff0c;用于对各类电源模块进行功能和性能测试。它采用模块化设计&#xff0c;构建了一个方便快捷、功能齐全的电源测试平台&#xff0c;便于后续的检修和维护&#xff0c;减少对企业生产和测试的影响。 电源自动测试系统的工作原理和…

区块链学习笔记3--以太坊

智能合约&#xff1a;跑在以太坊系统中的代码合同&#xff0c;其实质是一段代码。目前已经存在180多万个智能合约。 智能合约能表达&#xff1a;规则明确&#xff0c;不受主观因素影响的业务。 智能合约能表达&#xff1a;规则不轻易修改的业务 如果业务的规则经常变化&#x…

2025第九届数字信号处理国际会议(ICDSP 2025)将在成都召开!

第九届数字信号处理国际会议&#xff08;ICDSP 2025&#xff09;将于2025年2月21-23日在成都召开。ICDSP 2025大会由西南交通大学和西华大学联合主办, 并得到各地高校和机构的技术支持。大会旨在邀请众多国内外学者及产业研发人员齐聚一堂&#xff0c;共同探讨数字信号处理领域…

ABB机械手备份与恢复

ABB机械手备份与恢复 备份恢复系统 备份 ABB机器人数据备份的对象是所有正在系统内存中运行的RAPID程序和系统参数。当机器人系统出现错乱或者重新安装系统以后&#xff0c;可以通过备份快速地把机器人恢复到备份时的状态。 如果导出到U盘需要将U盘插入USB接口&#xff0c;位置…

docker-01 创建一个自己的镜像并运行容器

docker-01 创建一个自己的镜像并运行容器 前言 我们都知道使用Docker的镜像可以快速创建和部署应用&#xff0c;大大的节约了部署的时间。并且Docker 的镜像提供了除内核外完整的运行时环境&#xff0c;确保代码的环境一致性&#xff0c;从而不会在出现这段代码在我机器上没问…

通过mxGraph在ARMxy边缘计算网关上实现工业物联网

在当今的工业4.0时代&#xff0c;工业物联网&#xff08;IIoT&#xff09;已经成为制造业转型升级的关键技术之一。ARMxy边缘计算网关作为工业自动化和物联网的重要组成部分&#xff0c;能够为工厂车间提供实时的数据处理能力和智能化服务。而mxGraph作为一种流行的JavaScript库…

ABB的IO板卡配置

ABB的IO板卡配置 标准IO板卡DSQC651IO板卡的配置数字量输入信号配置数字量输出信号配置组合输入信号配置组合输出信号配置模拟量输出信号配置 标准IO板卡DSQC651 DSQC651可以处理8路输入数字量&#xff0c;8路输出数字量和2路模拟量输出信号。 X1是数字量输出&#xff0c;接线…

agentuniverse快速开始和踩坑

https://github.com/alipay/agentUniverse/tree/mastergithub地址:https://github.com/alipay/agentUniverse/tree/master 老大看了演示demo也想跟着做个agent工具,但踩坑太多,含泪写下博客 前置环节 git clone https://github.com/alipay/agentUniverse.git conda create -n…

轻松发高分的好思路:GNN+时间序列预测!新SOTA效率翻了5倍

在时序预测领域&#xff0c;通过合理构建和应用图结构&#xff0c;GNN能有效捕捉时空数据中的复杂依赖关系&#xff0c;轻松提高预测的准确性。因此GNN时序预测在学术界和工业界都广受欢迎。 最近这个方向出现了很多效果很好的研究&#xff0c;比如GraFITi模型&#xff0c;利用…

[AHK]Listbox with incremental search

可以根据文本框中的输入内容&#xff0c;实时动态从列表中搜索并定位所搜索内容。 AHK V1代码 #Requires AutoHotkey v1.0 Gui Add, Edit, w300 h20 vsearchedString gIncrementalSearch Gui Add, ListBox, vchoice gListBoxClick w300 h250 hscroll vscroll Gui Add, Button, …

Excel怎么截图?快速捕捉工作表的多种方法

大家好&#xff0c;这里是效率办公指南&#xff01; &#x1f4f8; 在日常工作中&#xff0c;我们经常需要对Excel工作表进行截图&#xff0c;无论是为了记录数据、制作演示还是进行数据对比。今天&#xff0c;我们就来学习几种在Excel中截图的方法以及它们的快捷键。 一、使…

迈向智能制造:数字化转型的核心策略与实践

在全球经济不断变革的背景下&#xff0c;制造业正迎来一场深刻的数字化变革。随着技术的快速进步&#xff0c;特别是工业4.0概念的普及&#xff0c;制造企业正在向智能制造方向转型。 智能制造是通过数字化技术的集成和应用&#xff0c;全面提升制造过程的自动化、信息化和智能…

Java项目: 基于SpringBoot+mybatis+maven新闻推荐系统(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven新闻推荐系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…