如何在30秒内学会使用pprof分析Go

简介: 如何在30秒内学会使用pprof分析Go

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

假设下面的代码是你要分析的 Go 代码:

package main
import (
    "fmt"
    "sync"
    "time"
)
// 模拟耗时操作
func hardWork(wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Printf("Start: %v\n", time.Now())
    // 模拟耗内存
    a := []string{}
    for i := 0; i < 500000; i++ {
        a = append(a, "aaaa")
    }
    // 模拟阻塞操作
    time.Sleep(2 * time.Second)
    fmt.Printf("End: %v\n", time.Now())
}
func main() {
  // 启动一个协程来执行 hardWork,并且等待它执行完成
    var wg sync.WaitGroup
    wg.Add(1)
    go hardWork(&wg)
    wg.Wait()
}

现在我们通过 pprof 来对其进行分析,我们需要做如下步骤:

  1. 安装 graphviz,这可以让我们以图形的形式来展示分析结果。mac 下通过 brew install graphviz 来安装,windows 下的安装可以自行在 csdn 搜索一下
  2. 安装 pprof:go get -u github.com/google/pprof
  3. 在 Go 代码中添加导入:import _ "net/http/pprof"
  4. 添加 pprof 的 web 端口:
go func() {
  fmt.Println(http.ListenAndServe("localhost:6060", nil))
}()

最终代码是下面这样的:

package main
import (
    "fmt"
    "net/http"
    "sync"
    "time"
    _ "net/http/pprof"
)
// 模拟耗时操作
func hardWork(wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Printf("Start: %v\n", time.Now())
    // 模拟耗内存
    a := []string{}
    for i := 0; i < 500000; i++ {
        a = append(a, "aaaa")
    }
    // 模拟阻塞操作
    time.Sleep(2 * time.Second)
    fmt.Printf("End: %v\n", time.Now())
}
func main() {
    var wg sync.WaitGroup
    // pprof 分析结果的界面
    go func() {
        fmt.Println(http.ListenAndServe("localhost:6060", nil))
    }()
  // 启动一个协程来执行 hardWork,并且等待它执行完成
    wg.Add(1) // 等待 pprof 协程
    wg.Add(1) // 等待 hardWork 完成
    go hardWork(&wg)
    wg.Wait()
}

接着,我们在控制台执行下面的命令:

go tool pprof http://localhost:6060/debug/pprof/heap

我们会进入一个交互式的命令行:

Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap
Saved profile in /Users/ruby/pprof/pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz
Type: inuse_space
Time: Jan 11, 2024 at 10:21am (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof)   // 我们可以在这里输入不同的命令

接着,我们在这个交互式的命令行中输入 png,它就会在我们项目的根目录下生成了一个分析结果的图片(注意:需要安装 graphviz):

另一种查看分析结果的方式

当然,命令行这种方式还是不太方便,我们可以直接打开浏览器访问:

http://localhost:6060/debug/pprof/

在这个页面,我们只需要通过鼠标点击就可以看到不同的性能指标了:

在这里,我们可以很容易查看我们的 Go 程序的一些性能指标,比如:

  • 内存
  • 协程
  • 阻塞


目录
相关文章
|
7月前
|
存储 消息中间件 大数据
Go语言在大数据处理中的实际应用与案例分析
【2月更文挑战第22天】本文深入探讨了Go语言在大数据处理中的实际应用,通过案例分析展示了Go语言在处理大数据时的优势和实践效果。文章首先介绍了大数据处理的挑战与需求,然后详细分析了Go语言在大数据处理中的适用性和核心技术,最后通过具体案例展示了Go语言在大数据处理中的实际应用。
|
7月前
|
负载均衡 算法 数据库连接
Go语言性能优化实践:案例分析与解决方案
【2月更文挑战第18天】本文将通过具体的案例分析,探讨Go语言性能优化的实践方法和解决方案。我们将分析几个典型的性能瓶颈问题,并详细介绍如何通过优化代码、调整并发模型、改进内存管理等方式来提升程序的性能。通过本文的学习,读者将能够掌握一些实用的Go语言性能优化技巧,为实际项目开发中的性能优化工作提供指导。
|
Java 编译器 Go
Go 语言逃逸分析
Go 语言逃逸分析
57 0
|
1月前
|
安全 Go 开发者
代码之美:Go语言并发编程的优雅实现与案例分析
【10月更文挑战第28天】Go语言自2009年发布以来,凭借简洁的语法、高效的性能和原生的并发支持,赢得了众多开发者的青睐。本文通过两个案例,分别展示了如何使用goroutine和channel实现并发下载网页和构建并发Web服务器,深入探讨了Go语言并发编程的优雅实现。
34 2
|
2月前
|
算法 Java 编译器
你为什么不应该过度关注go语言的逃逸分析
【10月更文挑战第21天】逃逸分析是 Go 语言编译器的一项功能,用于确定变量的内存分配位置。变量在栈上分配时,函数返回后内存自动回收;在堆上分配时,则需垃圾回收管理。编译器会根据变量的使用情况自动进行逃逸分析。然而,过度关注逃逸分析可能导致开发效率降低、代码复杂度增加,并且对性能的影响相对较小。编译器优化通常比人工干预更准确,因此开发者应更多关注业务逻辑和整体性能优化。
|
2月前
|
算法 安全 Go
Python与Go语言中的哈希算法实现及对比分析
Python与Go语言中的哈希算法实现及对比分析
42 0
|
2月前
|
机器学习/深度学习 自然语言处理 Go
Python与Go在AIGC领域的应用:比较与分析
Python与Go在AIGC领域的应用:比较与分析
55 0
|
4月前
|
编译器 Go
Go中init()执行顺序分析
文章分析了Go语言中`init()`函数的执行顺序和时机,指出全局变量初始化后先于`init()`函数执行,而`init()`函数在`main()`函数之前执行,且包的`init()`函数按包的导入顺序进行初始化。
34 1
|
4月前
|
存储 编译器 Go
Go语言中的逃逸分析
Go语言中的逃逸分析
|
4月前
|
设计模式 Java 编译器
Go - 基于逃逸分析来提升程序性能
Go - 基于逃逸分析来提升程序性能
46 2