C# C语言中的调用堆栈限制#

C# C语言中的调用堆栈限制#,c#,stack-overflow,callstack,limits,C#,Stack Overflow,Callstack,Limits,我想知道在我们得到堆栈溢出异常之前,我们可以在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) {

我想知道在我们得到堆栈溢出异常之前,我们可以在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,但这个数字不是常数,所以它是如何工作的?

每个线程都有一个堆栈大小。程序主线程的预定义堆栈大小在exe文件中是固定的。每次进行递归调用时,都会消耗一小部分堆栈。完成后,CLR将抛出一个
StackOverflowException
。对于控制台/图形程序,默认堆栈大小应为1mb内存。您不能从程序内部将此内存变大(您可以使用editbin.exe从程序外部将其更改)。这种记忆不是动态的。它是固定的(从技术上讲,为该内存保留的地址空间是固定的,内存实际上是由Windows操作系统按需分配的,一次可能分配4kb,但总是达到保留的地址空间)。您可以创建具有所需堆栈大小的辅助线程

请注意,以这种方式处理堆栈是x86/x64体系结构的一个限制:

某些处理器系列(如x86)具有用于操作当前执行线程堆栈的特殊指令。其他处理器系列,包括PowerPC和MIPS,没有明确的堆栈支持,而是依赖于操作系统的应用程序二进制接口(ABI)的约定和委托堆栈管理


从技术上讲,编译器不会抛出此异常,而运行时会抛出。。。这是如何发生的?@Bradleydotnett堆栈中的空间是恒定的,而不是恒定数量的函数调用。参数的大小是否会影响堆栈或方法内部变量的大小?在.NET的默认实现中,堆栈主要由三个部分填充:未“关闭”的局部变量通过匿名函数/yield/async(这些其他变量被移动到一个单独的类),一些数据用于堆栈跟踪,一些数据用于
最终
/
捕获
。请注意,引用类型在堆栈上只占用引用的大小,因此(局部变量)
int[]a=new int[100]
占用堆栈上引用的空间,加上堆中某个地方的
new int[100]
的大小。感谢您的回答;)。。。我希望.net更智能一些……例如,在调用之间找到一个无限循环,然后抛出异常@xanatos@M.kazemAkhgary,阅读。