GoLand 2025.3 Help

阻塞分析器

阻塞分析器显示 goroutine 未运行而处于等待状态的时间段。 这有助于识别由无缓冲或已满的 channel、 sync.Mutex 锁或其他同步问题引起的瓶颈。

GoLand 收集并可视化 CPU 分析、跟踪与堆分析数据。 为了收集所有必要的数据,GoLand 使用了 pprof 包。 GoLand 包含四种分析器,您可以通过用户界面运行它们:CPU、内存、阻塞(争用)和互斥锁。

分析结果可帮助您定位性能问题,但代码优化需手动实现。 有关详情,请参阅 Profiling at go.devpkg.go.dev 上的 pprof 软件包 描述。

分析完成后,分析器会在报告中可视化结果。

在开始之前

在运行分析前,请确保:

  • Go 已安装,您可以使用 GOROOT 文章来安装、升级或配置 Go。 欲了解更多信息,请参阅 GOROOT

  • GoLand 已在您的计算机上 安装

  • 您要分析的 Go 项目已在 IDE 中打开。

本主题中的所有示例均包含在一个 GitHub 上的示例项目中。

阻塞分析

阻塞分析器有助于检测由于 goroutine 等待无缓冲 channel、同步原语或其他阻塞操作而导致的延迟。 它会显示您的代码在等待而非执行时所耗费的时间及其位置。

示例程序

以下程序模拟一个生产者通过 channel 发送值,以及一个逐个处理数据的慢速消费者。 由于消费者较慢,生产者在尝试发送新数据时经常被阻塞:

import "time" var Ch = make(chan int) func InefficientConsumer() { for val := range Ch { time.Sleep(time.Second) // slow processing println("Received:", val) } } func InefficientProducer() { for i := 0; i < 5; i++ { Ch <- i } close(Ch) }

运行此代码会立即产生输出,但生产者 goroutine 在等待消费者准备就绪时会频繁暂停。

为分析创建测试

要分析阻塞行为,请为该程序创建单元测试:

package main import "testing" func TestInefficientConsumer(t *testing.T) { go InefficientProducer() InefficientConsumer() } func TestEfficientConsumer(t *testing.T) { go EfficientProducer() EfficientConsumer() }

运行阻塞分析器

  1. 打开 _test.go 文件。

  2. 点击测试函数旁边装订区域中的 运行 图标。

  3. 请选择 使用 Blocking Profiler 进行分析

    运行阻塞分析器

分析阻塞分析结果

GoLand 以三种视图呈现阻塞分析数据:

  • 火焰图 :显示函数调用以及 goroutine 处于等待(非运行)状态的时间。 每个块表示堆栈中的一个函数。 Y 轴表示堆栈深度(自下而上),X 轴表示堆栈分析,按升序排列:可根据延迟次数(已选 争用 )或总等待时间(已选 延迟 )排序。

    火焰图 选项卡中,鼠标悬停在任一块上可查看详细信息。

  • 调用树 :可视化函数间的调用关系,显示每个函数的延迟次数(争用 )或总等待时间(延迟)。 数据按降序排列,以突出最耗时的操作。 要配置或筛选 调用树 视图,请使用 表示设置 按钮 Presentation Settings 按钮

  • 方法列表 :按争用次数对所有方法进行排序。 反向跟踪 选项卡显示所选方法的调用位置, 合并的被调用方 选项卡显示所有源自该方法的调用跟踪。 被调用方列表 是汇总调用层次结构中所有方法的方法列表。

优化并比较结果

为解决阻塞问题,您可以使用带缓冲的 channel,以便生产者在消费者处理数据前发送多个值:

var BufCh = make(chan int, 3) func EfficientProducer() { for i := 0; i < 5; i++ { BufCh <- i } close(BufCh) } func EfficientConsumer() { for val := range BufCh { time.Sleep(time.Second) // slow processing println("Received:", val) } }

重新运行阻塞分析器后,火焰图显示的阻塞事件减少,等待时间缩短。 这确认了使用缓冲 channel 有助于减少同步延迟。

重新运行阻塞分析器

将带缓冲 channel 的用法与先前实现进行比较。

运行阻塞分析器
最后修改日期: 2025年 12月 5日