C#chunked数组

时间:2010-11-03 15:03:28

标签: c# arrays memory-management ilist

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

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

您是否了解IList兼容阵列的一些实现,这些阵列以块的形式分配内存而不是一次性分配内存?这样可以避免我的内存碎片问题。

3 个答案:

答案 0 :(得分:3)

Josh Williams在他的博客上使用分块数组提出了BigArray<T>课程:

  

<强> BigArray<T>, getting around the 2GB array size limit

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

  

C# huge size 2-dim arrays

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

call "$(DevEnvDir)..\tools\vsvars32.bat"
editbin.exe /LARGEADDRESSAWARE "$(TargetPath)"

答案 1 :(得分:1)

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

  1. 您可以尝试使用类似LinkedList<T>的内容,以避免需要连续分配,或重新构建代码以使这些块更小(尽管您不会完全安全,这不会发生一个500Mb阵列也。)

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

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

  4. 最后,您可以在自定义类中简单地实现IList接口,并在引擎盖下使用几个较小的阵列。

答案 2 :(得分:0)