简单的c#数组抛出OutOfMemory异常
本文关键字:OutOfMemory 异常 数组 简单 | 更新日期: 2023-09-27 18:17:32
我有一个相当大、相当简单的数组,它跟踪750,000个条目。在64位的。net中它工作得很好;然而,在32位客户端它失败与OutOfMemory
异常。我知道我没有耗尽内存。需要此程序的客户端无法使用64位版本。
以下伪代码编译(edit:原始代码没有不编译,由于拼写错误,这已经修复),并抛出相同的异常,当针对x86架构时,两台机器:
- Windows XP, 32位机器,运行4gb内存和。net Framework 4
- Windows 7, 64位机器,运行8gb内存和。net Framework 4
Edit:将编译器标志显式地切换到以针对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();
}
}
}
编辑:
这个代码运行的网络是一个封闭的网络,没有外部网络连接,所以发布更准确的代码和相关的异常细节是我正在研究的一个过程。我确实有智能运行,具有完整的调试符号和一些编译器开关,一旦我将其移植到互联网连接的网络,就会有更多细节。
在两台机器上,代码的索引都是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应用程序池中)。
考虑到其他用户已经报告无法重现错误,这似乎可能是环境或硬件特定的。是否有网络监控工具或反病毒程序触发这两个代码实现?如果是这样,是否有更好的/推荐的方法来初始化数组,以便我避免这种情况?
也许这会有帮助?
数组的最大容量是多少?
答案说也许使用List可以使用更少的内存
在没有更多调试信息的情况下,我猜测您的程序使用了虚拟内存。使用任务管理器查看所有已使用的内存,您必须将这些字段添加到进程资源管理器中。
根据记录,来自Jeffrey Richter(线程工作章节):
一个32位进程最多有2gb的可用地址空间。在加载了一堆Win32 dll,加载了CLR dll,分配了本机堆和托管堆之后,大约有1.5 GB的地址空间剩余。
尝试创建更多线程将导致抛出OutOfMemoryException。
当然,64位进程提供8tb的地址空间,因此理论上可以创建数十万个线程
初始化数组后,可用的空间越来越少。在某个时刻,你没有空的内存,你得到了你的OutOfMemoryException
。
我认为LINQ的使用更明智地利用了资源,并且在某些情况下它可以正常工作。
很遗憾,你不能用它做很多事情,很抱歉。你唯一能做的就是
- 不要在数组中使用太多的对象
- 更频繁地使用
GC.Collect
来收集不再使用的对象
尝试使您的存储struct
而不是class
值类型数组比引用类型数组消耗的内存少