C# 简单C数组抛出OutOfMemory异常

C# 简单C数组抛出OutOfMemory异常,c#,.net,arrays,out-of-memory,C#,.net,Arrays,Out Of Memory,我有一个相当大、相当简单的数组,它跟踪750000个条目。在64位.NET中,它运行良好;然而,在32位客户端上,它失败了,出现了OutOfMemory异常。我知道我的内存没有用完。需要此程序的客户端无法使用64位版本 以下伪代码编译编辑:由于键入错误,原始代码未编译,这已修复,并且在两台计算机上针对x86体系结构时引发相同的异常: Windows XP 32位计算机,运行4GB内存和.NET Framework 4 Windows 7 64位计算机,运行8GB RAM和.NET Framewo

我有一个相当大、相当简单的数组,它跟踪750000个条目。在64位.NET中,它运行良好;然而,在32位客户端上,它失败了,出现了OutOfMemory异常。我知道我的内存没有用完。需要此程序的客户端无法使用64位版本

以下伪代码编译编辑:由于键入错误,原始代码未编译,这已修复,并且在两台计算机上针对x86体系结构时引发相同的异常:

Windows XP 32位计算机,运行4GB内存和.NET Framework 4 Windows 7 64位计算机,运行8GB RAM和.NET Framework 4 编辑:将编译器标志切换为显式以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在运行,有完整的调试符号和一些编译器开关,当我把它移植到一个连接internet的网络上时,更多的细节就要跟进了

在这两台机器上,代码的索引在XP上都是693000 693002,确切地说在Windows7上是693646

有人知道问题是什么吗?当我在代码之后进行转储和配置文件时,我几乎不使用25MB的RAM

如果它给我买了什么东西,我会切换到不安全/非托管,但我唯一的尝试就是无法使用我的存储类

更新: 似乎有几个人无法在不同的机器/网络上复制问题,包括我自己

然而,我提出了一个使用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应用程序池中的其他计算机上


考虑到其他用户已经报告无法重现该错误,它似乎可能是特定于环境或硬件的。这两个代码实现上是否会触发网络监控工具或反病毒程序?如果是这样,是否有更好的/推荐的方法来初始化阵列,以避免出现这种情况?

如果没有更多的调试信息,我的猜测是您的程序使用虚拟内存。使用taskmanager浏览所有使用的内存,您必须将这些字段添加到process explorer中。如果这是cae,您的内存确实已用完。

有关记录,请参阅Jeffrey Richter《线程工作》一章:

32位进程中最多有2GB的可用地址空间。在大量Win32 DLL加载、CLR DLL加载、本机堆和托管堆分配完毕后,剩余的地址空间约为1.5 GB

尝试创建更多线程将导致抛出OutOfMemoryException

当然,64位进程提供8 TB的地址空间,因此理论上可以创建数十万个线程

因此,在初始化阵列之后,可用空间越来越少。在某个时刻,你们并没有空的内存,你们得到了OutOfMemoryException

我认为LINQ的使用更明智地使用了资源,而且在某些情况下,它可以正常工作

不幸的是,你不能用它做很多事情,对此很抱歉。你唯一能做的事

不要在数组中使用太多对象 更频繁地使用GC.Collect来收集不再使用的对象 尝试将存储结构改为类 vlaue类型数组消耗的内存比引用类型数组少

这可能会有帮助吗


答案是使用列表可能会占用更少的内存。

如果使用短计数,则使用年;你可以把你的存储空间减少一半。那篇文章并没有解决这个问题,但它确实将频率从1/5降低到了1/1700左右;我已经找到了一种捕获它并重试它的方法,这不是最有效地使用资源,但它是有效的,而且它通常是可以接受的。由于引用了一种类型本身,这是不可能的。