2

这是一个没有实际意义的问题,因为我分配的金额是错误的。它应该是 400MB 而不是 400GB……对不起!不过答案很好。

我正在尝试对我的一种方法进行单元测试,如果上传了大文件,该方法会引发 OutOfMemoryException。

我的问题是我的单元测试也抛出了这个异常(我猜是出于同样的原因)。

根据任务管理器的说法,如果我正确阅读了信息,我确实有足够的 RAM,所以我不确定为什么我的单元测试会以这种方式失败。

内存使用情况

这是各自的单元测试代码:

var data = new List<byte>();
for(UInt64 i = 0; i < 400ul * 1024ul * 1024ul * 1024ul; i += 65536ul)
{
    data.AddRange(new byte[65536]); // <-- throws exception here when i = 536870912
}
this.UploadedFileData = data.ToArray();

我在上面的代码之前尝试了以下内容:

var data = new byte[400ul * 1024ul * 1024ul * 1024ul];

但是,这会导致错误:算术运算导致溢出。

4

2 回答 2

4

你是32位机吗?

除非您使用 /3GB 引导开关,否则 32 位的进程限制为 2GB。

C# 增加堆大小 - 是否可能

您可能需要执行以下操作

对于非常大的 List 对象,您可以通过在运行时环境中将 gcAllowVeryLargeObjects 配置元素的 enabled 属性设置为 true 来将 64 位系统上的最大容量增加到 20 亿个元素。

来自http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

正如大卫所提到的,代码在增长时将需要大量的重新分配。为了防止性能成本和内存碎片,您至少应该设置Capacity一个适当的数量,如果不重写代码的话。

于 2013-01-11T06:20:11.927 回答
1

很可能您正在达到最大分配大小限制(大多数版本为 2GB)并且它需要抛出一些东西 - OOM 非常适合。

此处涵盖了限制:在 CLR 4.0 中,单个对象的大小仍限制为 2 GB?

旁注:由于需要将基础数据存储在连续的内存块中,因此您希望将它们缓慢增长到巨大的大小MemoryStream,这是不好的选择。List预先分配必要的存储量或使用自定义分块流/列表。

在 4.5 CLR 之前获得大约 2Gb 分配限制的数组示例 - http://blogs.msdn.com/b/joshwil/archive/2005/08/10/450202.aspx

于 2013-01-11T06:31:34.537 回答