【go 语言】PProf 的使用——协程(goroutine)和锁(mutex)分析(三)

简介: 【go 语言】PProf 的使用——协程(goroutine)和锁(mutex)分析(三)

正文


一、Goroutine Profiling:


1. 源代码:


package main
import (
    "net/http"
    _ "net/http/pprof"
    "runtime"
    "sync"
)
func init() {
    runtime.SetMutexProfileFraction(1)
    runtime.SetBlockProfileRate(1)
}
func main() {
    var m sync.Mutex
    var datas = make(map[int]struct{})
    for i := 0; i < 999; i++ {
        go func(i int) {
            m.Lock()
            defer m.Unlock()
            datas[i] = struct{}{}
        }(i)
    }
    _ = http.ListenAndServe("0.0.0.0:2022", nil)
}


12.webp.jpg


2. 协程(goroutine)分析


项目更目录下执行 go tool pprof http://127.0.0.1:2022/debug/pprof/goroutine,结束之后会默认进入 PProf 的命令行交互模式,接着执行 traces,如下图,


15.webp.jpg


  • 在查看 goroutine 时可以使用 traces 命令,这个命令会打印出对应的所有调用栈,以及指标信息。通过这个命令我们可以很方便地查看整个调用链路有什么,分别在哪里使用了多少个 goroutine,并且通过分析可以知道谁才是真正的调用方。


  • 调用栈的展示顺序是自下而上的,也就是说,runtime.main 方法调用了 main.main 方法,而 main.main 方法又调用了 net/http.ListenAndServe 方法,这里对应的就是我们使用的示例代码了,非常方便。


  • 每个调用栈信息都用 ------- 分隔,函数方法前的是指标数据。例如,Goroutine Profiling 展示的是该方法占用的 goroutine 的数量,而 Heap Profiling 展示的是占用的内存大小。


3. 锁(mutex)分析


项目更目录下执行 go tool pprof http://127.0.0.1:2022/debug/pprof/mutex,结束之后会默认进入 PProf 的命令行交互模式,接着执行 top,如下图,


16.webp.jpg

接着执行 list main (list 命令,查看指定函数的代码情况(包含特定的指标小心,如耗时)。若函数名不明确,则默认会对函数名进行模糊匹配),如下图

17.webp.jpg


从输出的分析中可以比较准确地看到引起互斥锁的函数,以及锁开销的位置(在本例中是第 23 行)。


4. 阻塞(block)分析


项目更目录下执行 go tool pprof http://127.0.0.1:2022/debug/pprof/block,结束之后会默认进入 PProf 的命令行交互模式,接着依次执行 toplist main,如下图,

18.webp.jpg


list main 命令的输出结果来看,程序在第 22 行阻塞。

目录
相关文章
|
9天前
|
Java 编译器 Go
go的内存逃逸分析
内存逃逸分析是Go编译器在编译期间根据变量的类型和作用域,确定变量分配在堆上还是栈上的过程。如果变量需要分配在堆上,则称作内存逃逸。Go语言有自动内存管理(GC),开发者无需手动释放内存,但编译器需准确分配内存以优化性能。常见的内存逃逸场景包括返回局部变量的指针、使用`interface{}`动态类型、栈空间不足和闭包等。内存逃逸会影响性能,因为操作堆比栈慢,且增加GC压力。合理使用内存逃逸分析工具(如`-gcflags=-m`)有助于编写高效代码。
|
15天前
|
存储 缓存 监控
企业监控软件中 Go 语言哈希表算法的应用研究与分析
在数字化时代,企业监控软件对企业的稳定运营至关重要。哈希表(散列表)作为高效的数据结构,广泛应用于企业监控中,如设备状态管理、数据分类和缓存机制。Go 语言中的 map 实现了哈希表,能快速处理海量监控数据,确保实时准确反映设备状态,提升系统性能,助力企业实现智能化管理。
29 3
|
4月前
|
安全 Go 数据处理
Go语言中的并发编程:掌握goroutine和channel的艺术####
本文深入探讨了Go语言在并发编程领域的核心概念——goroutine与channel。不同于传统的单线程执行模式,Go通过轻量级的goroutine实现了高效的并发处理,而channel作为goroutines之间通信的桥梁,确保了数据传递的安全性与高效性。文章首先简述了goroutine的基本特性及其创建方法,随后详细解析了channel的类型、操作以及它们如何协同工作以构建健壮的并发应用。此外,还介绍了select语句在多路复用中的应用,以及如何利用WaitGroup等待一组goroutine完成。最后,通过一个实际案例展示了如何在Go中设计并实现一个简单的并发程序,旨在帮助读者理解并掌
|
4月前
|
安全 Java Go
Go语言中的并发编程:掌握goroutine与通道的艺术####
本文深入探讨了Go语言中的核心特性——并发编程,通过实例解析goroutine和通道的高效使用技巧,旨在帮助开发者提升多线程程序的性能与可靠性。 ####
|
4月前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
362 4
|
4月前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
318 1
|
4月前
|
安全 Go 调度
探索Go语言的并发模型:goroutine与channel
在这个快节奏的技术世界中,Go语言以其简洁的并发模型脱颖而出。本文将带你深入了解Go语言的goroutine和channel,这两个核心特性如何协同工作,以实现高效、简洁的并发编程。
|
4月前
|
Go 调度 开发者
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。
|
4月前
|
安全 Go 开发者
代码之美:Go语言并发编程的优雅实现与案例分析
【10月更文挑战第28天】Go语言自2009年发布以来,凭借简洁的语法、高效的性能和原生的并发支持,赢得了众多开发者的青睐。本文通过两个案例,分别展示了如何使用goroutine和channel实现并发下载网页和构建并发Web服务器,深入探讨了Go语言并发编程的优雅实现。
66 2
|
4月前
|
安全 Go 调度
解密Go语言并发模型:CSP与goroutine的魔法
在本文中,我们将深入探讨Go语言的并发模型,特别是CSP(Communicating Sequential Processes)理论及其在Go中的实现——goroutine。我们将分析CSP如何为并发编程提供了一种清晰、简洁的方法,并通过goroutine展示Go语言在处理高并发场景下的独特优势。