2026-10-31·by Sijie Wang

Escape Analysis

逃逸分析:能证明不出函数就放栈,否则放堆

动机:堆分配贵,栈分配几乎免费。 堆分配慢,还要 GC 回收;栈分配就是挪一下栈指针,函数一退就没了,零成本。所以每个变量的问题就是:它能不能只活在栈上?能,但前提是它不出这个函数;一旦它可能活得比函数久,就必须上堆。

逃逸分析是编译器在编译时做的静态证明。 编译器分析每个变量的去向,证明它会不会离开函数。证明它永远不离开,就放栈上;证明不了、或者明确出去了,就放堆上。同一份代码,放哪儿由编译器能证明什么来定,写代码的人不用专门控制。

典型的逃逸。 变量在几种情况下会逃:被 return 出去,比如返回一个局部变量的指针;被存进活得更久的东西里,比如全局变量、map、slice、堆对象;被活得更久的闭包抓住;被传给 interface,编译器看不清动态类型;或者变量太大,栈放不下。

怎么看编译器的判决。 go build -gcflags=-m,编译器会逐个变量打印它是不是 moved to heap、为什么逃了。拿这个输出验你的分配猜想,别靠猜。

生产注记。 逃逸分析的意义是:代码老实写,分配真出现在 profile 里时再拿 -m 加 benchmark 去查,不是提前为了它把代码拧成麻花。变量放哪儿,编译器的证明说了算,不是程序员的猜测说了算。

about this entry

One of sijie's wiki entries. The AI on this site is grounded in the same corpus and answers in sijie's voice, with citations back to entries like this one — answering costs sijie money, so it waits behind a code: enter an access code →