逃逸分析分析。
逃逸分析有助于了解 Go 编译器为什么将值放入堆内存而不是栈内存。 堆分配会增加内存使用情况,并且给垃圾回收器带来更多工作。
GoLand 使用 go build -gcflags="-m" 命令运行逃逸分析。 GoLand 处理命令输出,并将结果应用到代码中。 这有助于在编辑器中直接导航到编译器消息、检查逃逸路径并了解优化决策。
运行逃逸分析
可以为文件或软件包运行逃逸分析。
为文件或软件包运行逃逸分析
请选择 从主菜单。
在 Go 性能优化 工具窗口中,选择 逃逸分析分析。。
选择作用域:
文件 :分析所选文件。
运行软件包 :分析所选软件包。
选择要显示的逃逸分析消息。
(可选)为 Go 进程指定环境变量。
点击 逃逸分析。

在编辑器中查看结果
分析完成后,GoLand 会在编辑器装订区域显示逃逸分析消息。
如果多条消息属于同一行,装订区域标记会显示该行的日志数量,例如 2 条日志。

检查装订区域消息
将鼠标悬停在装订区域标记上。
在弹窗中,查看编译器消息和逃逸路径。

也可以将鼠标悬停在函数名称上,查看该函数的逃逸分析结果。
从结果导航到代码
GoLand 也会在 Go 性能优化 工具窗口中显示逃逸分析结果。
点击工具窗口中的某个结果,即可导航到编辑器中的对应行。
导航到代码中的某个结果
请选择 从主菜单。
在 Go 性能优化 工具窗口中,选择要捕获的事件并点击 逃逸分析。
在结果选项卡中,展开某个文件、函数或消息类别。
点击结果。
GoLand 会将文本光标移动到编辑器中的对应行。
筛选器并分组结果
可在编辑器和工具窗口中筛选器逃逸分析消息。
筛选器逃逸分析消息
运行逃逸分析 后,在结果选项卡中,点击 筛选日志。
选择要显示的消息类型。
更改结果视图
点击 视图。
选择一种视图:
树 :以文件、函数和消息类型分组显示结果。

控制台输出 :显示
go build -gcflags="-m"命令的输出。 可在该视图中点击结果,导航到对应行。
分组结果
点击 按条件分组。
选择 GoLand 分组结果的方式,例如按函数或类别分组。
了解常见逃逸分析消息
逃逸分析用于判断值是否可以分配在栈上或必须分配到堆上。
许多堆分配是必要的,并不一定导致性能问题。 建议结合基准测试和性能分析结果一起使用逃逸分析,以查找影响性能关键代码的分配行为。
消息类型 | 描述 |
|---|---|
逃逸到堆 | 表示当前函数返回后某个值仍需被使用,因此必须将其分配到堆上。
func create() *int {
x := 10
return &x
}
在本示例中,函数返回 |
已移至堆 | 表示由于无法保证某个值在当前函数返回后不再被需要,编译器将其分配到堆上。
func process() {
value := 42
use(&value)
}
在本示例中,将 |
形参泄漏 | 表示函数参数逃逸到了当前函数之外,并可能在函数返回后仍需保持有效。
func store(p *int) *int {
return p
}
在本示例中,函数返回参数 |
可内联 | 表示该函数足够简单且体积小,编译器可在编译期间将函数调用替换为函数体内容。
func add(a, b int) int {
return a + b
}
在本示例中,函数包含一个简单操作且函数体很小。 编译器可以内联该函数,从而减少函数调用的开销并提升优化空间。 |
正在内联调用 | 表示编译器在编译期间将函数调用替换为函数体内容。
func add(a, b int) int {
return a + b
}
func main() {
_ = add(1, 2)
}
在本示例中,编译器直接在 可内联 表示某个函数符合内联条件。 正在内联调用 表示编译器实际内联了某个具体的函数调用。 |
其他 | 显示与逃逸分析和优化决策相关的额外编译器诊断信息。 |