> For the complete documentation index, see [llms.txt](https://gocompiler.shizhz.me/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gocompiler.shizhz.me/9.-golang-bian-yi-qi-tao-yi-fen-xi/9.1-shen-me-shi-tao-yi-fen-xi.md).

# 9.1 什么是逃逸分析

程序运行时将所使用的内存划分成两部分：

1. &#x20;栈（Stack） 函数的局部内存空间，用于保存函数的局部变量，也包括函数调用时的参数、返回值。栈内存与函数的生命周期完全一致，在函数调用时创建、退出时销毁，由程序自动管理，并且栈上数据仅对当前函数可见，因此，只要内存使用的生命周期在函数生命周期之内，都可以分配栈上的空间。

   &#x20;栈更加高效与安全，但对于使用场景有严格限制。
2. &#x20;堆（Heap） 全局内存空间，由整个程序共享。堆内存的分配与释放需要单独管理，像C语言有专门的分配与释放内存的内置函数，但现在几乎所有的高级编程语言都提供了自动的内存管理策略，Go 语言便是其中之一。由于堆内存的全局可见性，还需要保证并发访问下数据的同步性。

   &#x20;堆更加灵活，但面临着更复杂的管理问题，为程序带来了额外的开销。

由此可见，对于一个内存区域，它在程序中的可见范围决定了应该使用哪种内存：如果该内存区域的可见范围跨越了多个函数，那么就必须使用堆内存，而如果其可见范围仅仅局限于一个函数之内，则可以优先考虑栈空间。

程序的变量就是对内存区域的抽象，因此，对变量的可见范围（作用域）进行分析，进而判断应该将其分配到栈上还是堆上的过程，叫着逃逸分析。即为了简化内存管理，我们默认所有变量都使用栈空间，但如果一个变量由于被多个函数所引用，必须将其转移到堆上，我们就说该变量“逃逸”到了堆上。
