**栈(stack)**由编译器/运行时自动管理,存放函数调用的栈帧(局部变量、参数、返回地址),分配释放只是移动栈指针,速度极快,但空间小(通常每线程几 MB),生命周期随函数返回自动结束。**堆(heap)**由程序员或 GC 管理,用于存放动态分配、生命周期跨函数的大对象,空间大但分配慢,还可能产生碎片。
对比要点:
- 管理方式:栈自动;堆在 C/C++ 中需手动 new/delete(忘记释放即内存泄漏),Java/Go/JS 等靠 GC。
- 大小与增长:栈固定且小;堆受虚拟内存限制,大得多。
- 访问:栈上数据连续、缓存友好;堆靠指针间接访问。
栈溢出(stack overflow):栈空间被耗尽,最常见原因是无限或过深的递归(没有正确终止条件),其次是栈上分配超大局部数组。表现为程序崩溃(C 中 segmentation fault、Java 中 StackOverflowError)。
示例:
void f() { f(); } // 无限递归 → 栈溢出
void g() { int a[1<<24]; } // 栈上分配 16MB → 也可能溢出
追问方向:逃逸分析(JVM/Go 把对象分配在栈上)、尾递归优化、堆内存泄漏的排查。