目录一、什么是逃逸分析二、为什么需要逃逸分析?三、逃逸发生的常见场景1. 返回局部变量的指针2. 将变量赋值给包级全局变量或外部引用的指针3. 将变量传递给interface{}参数(可能逃逸,取决于函数内是否存储引用)-不必要改正方法4. 闭包捕获变量5. 切片或 map 存储指针(或本身需要扩容)-不必要改正方法6. 发送到 channel 的指针三、如何查看逃逸分析结果?四、逃逸分析与栈分配的关系图五、性能影响与优化建议性能差异优化建议六、典型反例:循环中取地址七、常见的坑八、总结一、什么是逃逸分析逃逸分析是 Go 编译器在编译阶段执行的一项静态分析技术,用于判断一个变量的内存是分配在栈上还是堆上。它的核心结论是:如果变量在函数返回后仍然可能被引用,则它会“逃逸”到堆上;否则,它优先分配在栈上。二、为什么需要逃逸分析?分配位置优点缺点栈上分配分配/释放极快(仅移动栈指针),无需 GC 扫描函数返回后自动销毁,无法跨函数保持堆上分配可跨函数访问,生命周期灵活分配较慢,需要 GC 管理,增加 GC 压力逃逸分析的目标:尽量把变量分配在栈上,减少堆分配,从而降低 GC 负担、提升性能。三、逃逸发生的常见场景1.返回局部变量的指针func newInt() *int { x := 42 return x // x 逃逸到堆上,因为返回后仍需访问 }2.将变量赋值给包级全局变量或外部引用的指针var global *int func setGlobal() { x := 42 global = x // x 逃逸到堆上 }3.将变量传递给interface{}参数(可能逃逸,取决于函数内是否存储引用)-不必要func printInterface(v interface{}) { fmt.Println(v) } func main() { x := 42 printInterface(x) // x 可能逃逸,因为 interface{} 可能持有引用 }为什么会逃逸?interface{}是一个包含类型和指