4

我需要分配非常大的简单结构数组(1 GB RAM)。在几次分配/解除分配之后,内存变得碎片化并引发 OutOfMemory 异常。

这是32位以下。由于我得到的性能损失,我宁愿不使用 64 位 - 相同的应用程序在 64 位模式下运行速度慢 30%。

您是否知道 IList 兼容数组的一些实现,它们以块的形式分配内存,而不是一次全部分配?这样可以避免我的内存碎片问题。

4

3 回答 3

3

Josh WilliamsBigArray<T>在他的博客上介绍了一个使用分块数组的课程:

BigArray<T>,绕过 2GB 数组大小限制

您将在此相关问题中找到更多有用的信息:

C# 巨大的 2-dim 数组

一个简单的临时修复可能是为您的应用程序启用 3GB 开关。这样做可以让您的应用程序使用超过 32 位 Windows 的每个进程 2GB 的限制。但是,请注意 CLR 允许的最大对象大小仍然是 2GB。可以使用主可执行文件的后构建操作启用该开关:

call "$(DevEnvDir)..\tools\vsvars32.bat"
editbin.exe /LARGEADDRESSAWARE "$(TargetPath)"
于 2010-11-03T15:07:38.400 回答
1

在实例化一个数组时,.Net 会尝试为您的数组找到一个连续的内存部分。由于 32 位应用程序的总内存限制为 2Gb,您可以看到在多次分配后很难找到这样的块。

  1. 您可以尝试使用 , 之类的东西LinkedList<T>来避免连续分配的需要,或者重组代码以使这些块更小(尽管您不会完全安全,但 500Mb 数组也不会发生这种情况)。

  2. 另一方面,一种解决方案是在应用程序启动时仅将这个大缓冲区实例化一次,然后实现一种算法,该算法将在应用程序的生命周期内重用相同的空间。

  3. 如果可以使用 IEnumerable 而不是 IList 将数据传递给程序的其余部分,则可以使用SelectManyLINQ 方法折叠此列表。

  4. 最后,您可以简单地在自定义类中实现 IList 接口,并在后台使用几个较小的数组。

于 2010-11-03T15:12:12.607 回答
0

LinkedList 对你有用吗? http://msdn.microsoft.com/en-us/library/he2s3bh7.aspx

于 2010-11-03T15:06:56.290 回答