无任何变量的递归方法为什么会触发Stack Overflow错误?
无变量递归栈溢出问题解答
方法本身不会存储在栈上
方法的可执行代码是存放在进程内存的代码段区域的,属于全局的只读指令数据,不会在每次调用时被拷贝到栈中,你认为「方法本身存栈上」的认知是错误的。
无变量依旧触发栈溢出的核心原因
哪怕方法没有任何输入参数、内部局部变量,每次方法调用都会在线程栈中压入一个栈帧,栈帧里最少包含两类必须存储的信息:
- 调用结束后的返回地址:CPU跑完当前方法的逻辑后,需要知道回到调用方的哪一行继续执行,这个地址会在发起方法调用时自动压入栈
- 栈基址指针:用于方法执行完成后,恢复上一个方法的栈上下文定位
你提供的代码属于没有终止条件的无限递归:
class MainClass { static void Main() => Bark(); static void Bark() { Bark(); } }
Bark会无限调用自身,每调用一次就压入一个新栈帧。而系统给每个线程分配的栈空间是固定的:Windows默认栈大小为1MB,Linux默认通常为8MB。哪怕每个栈帧只占用十几字节,累积数十万次调用后栈空间就会被完全占满,最终抛出栈溢出异常。
补充说明:部分场景下尾递归会被编译器/JIT优化,不会累积栈帧,比如C#在特定架构的Release模式下可能会优化这个递归,但这不是语言层面的强制保证,大多数情况下这个代码依然会触发栈溢出。
内容的提问来源于stack exchange,提问作者zeroG
相关产品推荐
相关产品推荐

