我的电脑有2GB的RAM内存。当我在C#2008 Express Edition中形成具有70.000个项目的数组的3D网格对象时,我收到错误消息“Stack Overflow exception handling ...”。如果我将RAM内存从2GB升级到4GB,我可以克服此错误消息吗?
答案 0 :(得分:19)
几乎肯定不。堆栈溢出(而不是内存不足)意味着您已经使用了已分配的堆栈空间 - 但堆栈(相对而言)很小。 堆就是它发生的全部......
选项:
答案 1 :(得分:11)
没有。增加RAM不会增加堆栈大小。
您正在编写导致堆栈溢出的代码(可能是由于递归),您需要修复它。
答案 2 :(得分:3)
物理内存仅影响机器中运行的程序的性能,但与程序的任何内存相关问题无关(在标准操作系统上,嵌入式系统遵循不同的规则)。
首先,因为我已经多次看到这个错误,让我们谈谈他的操作系统内存模型。
几乎每个用户操作系统(我在Linux,windows,bsd等上都在考虑)都使用虚拟内存模型。虚拟内存模型意味着每个程序都可以完全访问私有虚拟内存,即不必具有相应物理内存的内存存储表示。
此虚拟内存的大小等于单个机器寄存器可以寻址的范围。在32位操作系统上,这意味着大约4GB。现在,无论你的系统有多少实际内存,你的程序总会认为他有4GB。
现在,这些4GB实际上是在您的程序和操作系统保留的空间之间共享的,用于处理内核模式下的数据以及维护程序所需的结构。实际上,根据您的配置(您的操作系统配置),您可以计算大约2或3 GB。所有这些都与你拥有的物理内存量无关,你可以拥有256 MB的RAM,你的程序仍然认为他有2GB的空间。
分配内存时,系统通常无法准确提供您要求的内存量。相反,它使用页面,这些页面是保留内存块(例如4KB),分配给您的进程。当你这样做时,操作系统将“页面”注册为已分配,但这仍然在虚拟内存中。在内部,操作系统管理哪些页面保存在物理内存中,哪些页面在交换中(在HDD中)。这就是为什么增加你的内存会增加你的性能(更多的页面可以同时在主内存中,你必须从硬盘读取更少),但不会有助于堆栈溢出(或内存不足异常)方式)。
为什么增加内存无效。
最后,关于Stack Overflow异常......好在没有看到实际代码的情况下很难说,已经给出了一些好的答案。
大多数堆栈溢出来自无限递归,无论是直接还是间接(A - > B - > C - > A),但在具体情况下,我会说你只是分配给很多堆栈中的数据。
你有一个70000大小的数组。我猜这个数组充满了值类型,它们在堆栈中分配,如果我没记错的话(请不要把它当作事实)在.NET中是1MB,这可能就是你得到的原因你的堆栈溢出。
答案 3 :(得分:2)
可能不是。你应该increase the stack size,这就是错误信息所说的
编辑:或者修复代码中可能存在的无限递归。
答案 4 :(得分:2)
堆栈溢出可能意味着无限递归或非常深层嵌套的递归。
很明显,如果你有尾递归方法,x64 JITter将优化它们,你根本不会遇到堆栈溢出(你的无限递归将是......无限的)。
所以你可以升级到64位操作系统,或者修改你的代码以免陷入这个问题(这可能是一个错误而不是太深的嵌套递归......)
答案 5 :(得分:1)
实际上,没有。但我有一个不同的原因:除非在boot.ini中指定特定的引导选项,否则Windows XP最多只能处理2 GB。 (/ 3gb参数。)充其量,Windows XP和Vista将达到3 GB的RAM,这基本上是Windows的限制。 有关这些限制的详细信息,请参阅This link。
增加RAM并修复应用程序以超出2 GB的限制可能会修复堆栈溢出,因为它可能会增加堆栈的大小。它也可能只是延迟这个堆栈溢出的时刻,因为正如所建议的那样,你的代码处于一个无限的递归循环中,并且只会继续运行直到资源不足。
如果使用递归,请记住:使用递归执行的任何操作都可以在不使用递归的情况下重写。虽然代码不易阅读,但此规则没有例外。
答案 6 :(得分:0)
我不知道C#,但在java中,stackoverflow错误意味着您正在类中创建一个类的实例,该实例已在您尝试实例的类中实例化