【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 行阻塞。

目录
相关文章
|
5月前
|
人工智能 数据可视化 编译器
Go interface实现分析
本文深入探讨了Go语言中接口的定义、实现及性能影响。接口作为一种“约定”,包含方法签名集合,无需依赖具体类型即可调用方法,隐藏了内部实现细节。文章分析了接口的两种实现方式(iface和eface)、按值与按指针实现的区别,以及nil接口与普通nil的区别。同时,通过反汇编代码对比了接口动态调用与类型直接调用的性能差异,指出接口调用存在内存逃逸和无法内联的问题。最后总结了接口的优势与局限性,强调在实际开发中需根据场景合理选择是否使用接口。
114 13
|
4月前
|
存储 Go API
如何在 Go 中获取 goroutine 的 ID?
在 Go 语言中,Goroutine 是轻量级线程,但官方未提供直接获取 Goroutine ID 的 API,以避免开发者依赖其进行复杂操作。然而,在调试和日志跟踪时,获取 Goroutine ID 可能很有帮助。本文介绍了通过 `runtime.Stack` 解析调用栈信息提取 Goroutine ID 的方法,尽管性能较低,适合调试场景。同时推荐使用第三方包 `github.com/petermattis/goid`,它通过 C 和汇编实现更高效地获取 Goroutine ID。需要注意的是,Goroutine ID 不应用于业务逻辑,而应关注 Goroutine 行为与通道通信。
164 11
如何在 Go 中获取 goroutine 的 ID?
|
2月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
2月前
|
数据采集 消息中间件 编解码
Go语言实战案例:使用 Goroutine 并发打印
本文通过简单案例讲解 Go 语言核心并发模型 Goroutine,涵盖协程启动、输出控制、主程序退出机制,并结合 sync.WaitGroup 实现并发任务同步,帮助理解 Go 并发设计思想与实际应用。
|
4月前
|
数据采集 安全 Go
Go 语言并发编程基础:Goroutine 的创建与调度
Go 语言的 Goroutine 是轻量级线程,由 runtime 管理,具有启动快、占用小、支持高并发的特点。本章介绍 Goroutine 的基本概念、创建方式(如使用 `go` 关键字或匿名函数)、M:N 调度模型及其工作流程,并探讨其在高并发场景中的应用,帮助理解其高效并发的优势。
|
5月前
|
Go 调度
GO语言函数的内部运行机制分析
以上就是Go语言中函数的内部运行机制的概述,展示了函数在Go语言编程中如何发挥作用,以及Go如何使用简洁高效的设计,使得代码更简单,更有逻辑性,更易于理解和维护。尽管这些内容深入了一些底层的概念,但我希望通过这种方式,将这些理论知识更生动、更形象地带给你,让你在理解的同时找到编程的乐趣。
86 5
|
5月前
|
人工智能 安全 Go
Go语言中 Mutex 的实现原理
本文深入解析了 Go 中 `sync.Mutex` 的实现原理及其工作机制。`Mutex`(互斥锁)是并发编程中的基础同步机制,用于保护共享资源不被多个 Goroutine 同时访问。Go 的 `sync.Mutex` 通过轻量级的结构体实现,包含 `state` 和 `sema` 两个字段,分别用于表示锁状态和管理 Goroutine 的阻塞与唤醒。 文章详细分析了锁的获取(`Lock()`)和释放(`Unlock()`)过程,包括快速路径和慢速路径的实现逻辑。在慢速路径中,介绍了自旋锁优化、饥饿模式以及信号量机制的应用,确保高效且公平地管理锁竞争。
131 6
|
6月前
|
存储 监控 算法
员工行为监控软件中的 Go 语言哈希表算法:理论、实现与分析
当代企业管理体系中,员工行为监控软件已逐步成为维护企业信息安全、提升工作效能的关键工具。这类软件能够实时记录员工操作行为,为企业管理者提供数据驱动的决策依据。其核心支撑技术在于数据结构与算法的精妙运用。本文聚焦于 Go 语言中的哈希表算法,深入探究其在员工行为监控软件中的应用逻辑与实现机制。
159 14
|
7月前
|
Java 编译器 Go
go的内存逃逸分析
内存逃逸分析是Go编译器在编译期间根据变量的类型和作用域,确定变量分配在堆上还是栈上的过程。如果变量需要分配在堆上,则称作内存逃逸。Go语言有自动内存管理(GC),开发者无需手动释放内存,但编译器需准确分配内存以优化性能。常见的内存逃逸场景包括返回局部变量的指针、使用`interface{}`动态类型、栈空间不足和闭包等。内存逃逸会影响性能,因为操作堆比栈慢,且增加GC压力。合理使用内存逃逸分析工具(如`-gcflags=-m`)有助于编写高效代码。
147 2
|
8月前
|
存储 缓存 监控
企业监控软件中 Go 语言哈希表算法的应用研究与分析
在数字化时代,企业监控软件对企业的稳定运营至关重要。哈希表(散列表)作为高效的数据结构,广泛应用于企业监控中,如设备状态管理、数据分类和缓存机制。Go 语言中的 map 实现了哈希表,能快速处理海量监控数据,确保实时准确反映设备状态,提升系统性能,助力企业实现智能化管理。
145 3

热门文章

最新文章

下一篇
开通oss服务