8

我的电脑有 2GB 的 RAM 内存。当我在 C# 2008 Express Edition 中形成一个包含 70.000 个项目的数组的 3D 网格对象时,我收到错误消息“堆栈溢出异常处理...”。如果我将 RAM 内存从 2GB 升级到 4GB,我可以克服这个错误消息吗?

4

7 回答 7

19

几乎可以肯定不是。堆栈溢出(而不是内存不足)意味着您已经消耗了分配的堆栈空间 - 但堆栈(相对而言)很小。是所有事情发生的地方......

选项:

  • 修复你的无限递归错误......
  • 将数据移动到数组/列表/一些基于堆的存储中(现在在哪里?)
  • 避免深度递归
  • 避免过大的结构......你有一些真正应该是类的大胖结构吗?(如果你对它们眨眼,结构就会自我复制)
  • 如果您确信自己只是将其翻倒,则增加堆栈空间,并且不值得进行大的重构(我讨厌这个答案)-为此,您需要使用更大的堆栈生成自己的线程
于 2009-06-02T21:17:35.183 回答
11

不会。增加 RAM 不会增加堆栈大小。

您正在编写导致堆栈溢出的代码(可能是由于递归),您需要修复它。

于 2009-06-02T21:16:41.630 回答
3

物理内存只影响机器中运行的程序的性能,而与程序的任何内存相关问题无关(在标准操作系统上,嵌入系统遵循不同的规则)。

首先,因为这个错误我已经见过很多次了,我们来谈谈操作系统的内存模型。

几乎每个用户操作系统(我在这里考虑的是 linux、windows、bsd 等)都使用虚拟内存模型。虚拟内存模型意味着每个程序都可以完全访问私有虚拟内存,即不必具有相应物理内存的内存存储表示。

这个虚拟内存的大小等于单个机器寄存器可以寻址的范围。在 32 位操作系统上,这意味着大约 4GB。现在,不管你的系统有多少实际内存,你的程序总是认为他有 4GB。

现在,这 4GB 实际上是在您的程序和操作系统为在内核模式下处理数据以及维护程序所需结构而保留的空间之间共享的。根据您的配置(您的操作系统配置),您可以根据实际情况计算大约 2 或 3 GB。所有这些都与您拥有的物理内存量无关,您可以拥有 256 MB 的 RAM,但您的程序仍然会认为他有 2GB 可供使用。

当您分配内存时,系统通常不会准确地提供您要求的内存量。相反,它使用页面,这是分配给您的进程的保留内存块(例如 4KB)。当您这样做时,操作系统会将该“页面”注册为已分配,但这仍然在虚拟内存中。在内部,操作系统管理这些页面中的哪些保留在物理内存中,哪些在交换中(在 HDD 中)。这就是增加 RAM 可以提高性能的原因(更多页面可以同时在主内存中,并且您必须从 HDD 中读取更少)但无助于堆栈溢出(或内存不足异常)道路)。

这就是为什么增加 RAM 无济于事。

最后,关于 Stack Overflow 异常……好吧 不看实际代码很难说,已经给出了一些好的答案。

大多数堆栈溢出来自无限递归,无论是直接还是间接(A-->B-->C-->A),但在您的具体情况下,我会说您只是分配给堆栈中的大量数据。

你有一个 70000 大小的数组。我猜这个数组充满了值类型,它们被分配在堆栈中,如果我没记错的话(请不要把这当作事实)在.NET中是1MB,这可能是你得到的原因你的堆栈溢出。

于 2009-06-02T21:30:13.443 回答
2

堆栈溢出可能意味着无限递归或非常深的嵌套。

顺便说一句,如果您有尾递归方法,x64 JITter 将优化它们,您根本不会遇到堆栈溢出(并且您的无限递归将是......无限)。

所以你可以升级到 64 位操作系统,或者修复你的代码以免遇到这个问题(这更可能是一个错误而不是太深的嵌套递归......)

于 2009-06-02T21:28:09.767 回答
2

可能不是。您应该增加堆栈大小,这就是错误消息所说的

编辑:或者修复代码中可能存在的无限递归。

于 2009-06-02T21:19:11.080 回答
1

实际上,没有。但我有一个不同的原因:除非您在 boot.ini 中指定特定的引导选项,否则 Windows XP 最多只能处理 2 GB。(/3gb 参数。)在最好的情况下,Windows XP 和 Vista 将达到 3 GB 的 RAM,这基本上是 Windows 的限制。有关这些限制的更多信息,请参阅此链接

增加 RAM 并修复应用程序以超过 2 GB 限制可能会修复堆栈溢出,因为它可能会增加堆栈的大小。它也可能只是延迟此堆栈溢出的时刻,因为正如已建议的那样,您的代码处于无限递归循环中,并且将继续运行直到资源不足。

如果您确实使用递归,请记住这一点:您使用递归所做的任何事情都可以在不使用递归的情况下重写。这条规则没有例外,尽管代码不会更容易阅读。

于 2009-06-02T21:35:15.507 回答
0

我不知道 C#,但在 java 中,stackoverflow 错误意味着您正在创建已在您尝试实例化的类中实例化的类的实例

于 2013-01-21T23:56:04.863 回答