我想知道在我们得到堆栈溢出异常
之前我们可以在c#中执行多少调用所以我决定编写以下代码
static void Method2(int Calls)
{
if(!Calls.Equals(0))
Method1(--Calls);//if more calls remain call method1 and reduce counter
}
static void Method1(int Calls)
{
if (!Calls.Equals(0))//if more calls remain call method2 and reduce counter
Method2(--Calls);
}
static void Main(string[] args)
{
var Calls= 42994;//number of calls(stack overflow appears for large number)
Method1(Calls);
}
我的问题是编译器如何决定抛出堆栈溢出异常 这是关于内存限制的吗? 一旦我把42995我得到了stackoverflow但是这个数字不是常数所以这是如何工作的?
答案 0 :(得分:6)
每个线程都有一个堆栈大小。程序主线程的预定义堆栈大小在exe文件中修复。你做的每个递归调用,你消耗一点这个堆栈。完成后,CLR会抛出StackOverflowException
。对于控制台/图形程序,默认堆栈大小应为1mb内存。你无法从程序内部使这个内存变得“更大”(你可以使用 editbin.exe 将它从程序外部“更改”)。这个记忆不是动态的。它是固定的(从技术上讲,为这个内存保留的地址空间是固定的,内存实际上是由Windows操作系统按需分配的,一次可能是4kb,但总是高达保留的地址空间)。您可以使用所需的堆栈大小创建辅助线程。
请注意,以这种方式处理堆栈是x86 / x64架构的限制,http://en.wikipedia.org/wiki/Stack-based_memory_allocation:
某些处理器系列(如x86)具有操作当前正在执行的线程堆栈的特殊指令。其他处理器系列(包括PowerPC和MIPS)没有显式的堆栈支持,而是依赖于约定并将堆栈管理委托给操作系统的应用程序二进制接口(ABI)。