在.NET中的CLR上下文中,如何分配堆栈空间

时间:2011-05-12 07:22:33

标签: c# vb.net memory-management stack stack-overflow

在.NET中的CLR上下文中,如何分配堆栈空间以及它通常受限于什么?

例如:

在内存耗尽之前,任何给定的线程都可以继续添加到堆栈吗?如果不; CLR如何决定分配多少空间并改变主意呢?

PS:只是为了给它设置一些上下文,这一切都始于讨论如何构建一个计算Fibonacci序列的方法,其中一个建议是一个递归函数。

1 个答案:

答案 0 :(得分:4)

CLR会立即为每个线程提交完整的堆栈空间。默认堆栈大小为1MB。如果你将堆栈超过那个大小,那就是堆栈溢出并引发错误。

CLR采用与本机代码不同的策略,仅保留1MB但按需提交。

这些是实施细节。最好只将堆栈视为固定大小的数据结构。此视图适用于.net和本机堆栈实现。

递归函数是计算Fibonacci的绝对最差方法,因为它的复杂性是指数级的。相反,你应该使用迭代算法,该算法在时间上是线性的,在空间中是常数。例如:

static int fib(int n)
{
    int result = 0;
    int a = 1;
    for (int i=1; i<=n; i++)
    {
        int temp = result;
        result = a;
        a = temp + a;
    }
    return result;
}

当然,实际上,在到达堆栈溢出之前很久就会溢出结果变量。但是对于30-40范围内的n值,递归算法的性能是站不住脚的。

另一种明智的方法是用预先计算的值填充静态数组。同样,由于值增长如此之快,因此您不需要非常大的数组来包含适合int甚至long的所有值。