我有一个相当大而又相对简单的数组,跟踪着750,000个条目。在64位.NET中它可以正常工作,但是在32位客户端中会出现OutOfMemory
异常。我知道我并没有耗尽内存。需要运行此程序的客户端无法使用64位版本。
以下伪代码编译通过(编辑:原始代码由于拼写错误而未编译通过,已经修复),在两台机器上针对x86架构时都会抛出相同的异常:
- 一台安装了4 GB RAM和.NET Framework 4的Windows XP 32位机器
- 一台安装了8 GB RAM和.NET Framework 4的Windows 7 64位机器
编辑:将编译器标志切换为显式地针对x64架构,则可以在Windows 7 64位机器上运行。
using System;
public class Storage
{
Storage futureStorage;
int count;
int years;
bool isTest;
bool isSet;
}
public static class Program
{
public static void Main()
{
Storage[] storageArray = new Storage[750000];
for (int i = 0; i < 750000; i++)
{
storageArray[i] = new Storage();
}
}
}
编辑:
这段代码运行的网络是封闭网络,没有外部网络连接,因此发布更精确的代码和相关异常细节需要一些过程,我正在努力解决。我已经运行了intellitrace,具有完整的调试符号和一些编译器开关,更多细节将在我将其移植到互联网连接的网络后提供。
在两台机器上,代码在索引为693,000(确切地说,在XP上为693,002,在Windows 7上为693,646)时停止工作。
有人有什么想法,可能是什么问题?当我在代码后进行转储和分析时,我几乎没有使用25 MB的RAM。
如果使用不安全/非托管代码可以帮助我解决问题,我会切换,但我尝试过的唯一尝试使我无法使用我的Storage类。
更新:
似乎有几个人无法复制该问题(包括我在另一台机器/网络上)。
然而,我想出了一个解决方案(使用LINQ)来缓解这个问题,现在它只有1/5的概率抛出异常,有人知道使用此解决方案是否存在任何问题或注意事项,以及为什么内部可能会与其他解决方案不同?
using System;
using System.Linq;
public class Storage
{
Storage futureStorage;
int count;
int years;
bool isTest;
bool isSet;
}
public static class Program
{
public IEnumerable<Storage> storageEnumerable;
public static void Main()
{
storageEnumerable = (from x in Enumerable.Range(0, 750000) select new Storage() {count = x});
foreach (Storage s in storageEnumerable)
Console.WriteLine(x);
}
}
上述LINQ代码使用的内存要少得多,但异常仍然发生;而且只发生在这个网络中的机器上,而不是在网络之外的其他机器上(或者说在IIS应用程序池内)。
考虑到其他用户后来报告说不能重现这个bug,可能是由于环境或硬件特定引起。是否有网络监视工具或反病毒程序触发了这两个代码实现?如果是这样,有没有更好/推荐的方法来初始化数组,以避免这种情况?
short count, years;
,你可以将存储几乎减少一半。 - Peter Gluck