4

我对编程中的内存划分概念很陌生。我发现堆栈的大小在大多数情况下在 .NET 应用程序中为 1MB 左右。我的问题是:“在某些函数中我使用局部变量来表示大于 1MB 的“图像”类型时,堆栈溢出是如何出现的。提前致谢。

4

5 回答 5

7

因为StackOverflow异常与堆栈或堆内存管理无关。根据MSDN 文档

执行堆栈溢出时抛出的异常,因为它包含太多的嵌套方法调用。这个类不能被继承。

现在,如果您谈论的stack是就记忆而言,那么我们就在另一个世界中。您存储在内存中的图像可能保存在大对象堆上。内存管理及其讨论对于本论坛来说过于宽泛——但如果您有关于内存管理的具体问题,那么我们可以解决这个问题。

重要的是你要明白你在你的问题中混合了两个命名法和概念,并且两者之间有明显的区别。我不希望你继续认为你应该StackOverflow因为大对象而获得例外。我也不希望您继续认为由于大对象和内存管理而导致异常StackOverflow

于 2012-12-27T13:13:55.600 回答
6

图像本身不存储在堆栈中,它存储在堆中。只有一个指向图像的指针/引用保存在堆栈上,这要小得多。

public static void DoSomethingToImage()
{
    Image img = new Image(...);
}

在上面的代码片段中,图像被分配在堆上,并且对图像的引用存储在img堆栈上的变量中。

于 2012-12-27T13:13:22.213 回答
4

只有作为值类型的局部变量才仅在堆栈上分配。对于Image只有引用分配在堆栈上的引用类型,对象分配在堆上。

于 2012-12-27T13:14:21.280 回答
2

您的局部变量实际上是引用(“指针”)。这些图像不存储在堆栈中;)

于 2012-12-27T13:13:16.627 回答
1

发生堆栈溢出错误的主要原因是有大量的函数调用,通过此错误的示例如下:

static int x = 0;

static void Main()
{
    fn();
}

static void fn()
{
    Console.WriteLine(x++);
    fn();
}

发生这种情况是由于代码有问题,因为这通常发生在数千次调用之后。

上面的应用程序像这样退出:

...
15706
15707
15708
Process is terminated due to StackOverflowException.

您可以学习在调试器中查看“调用堆栈”窗口,它将显示函数调用列表。

于 2012-12-27T14:45:16.277 回答