我需要分配非常大的简单结构数组(1 GB RAM)。在几次分配/解除分配之后,内存变得碎片化并抛出OutOfMemory异常。
这低于32位。由于我得到的性能损失,我宁愿不使用64位 - 相同的应用程序在64位模式下运行速度减慢30%。
您是否了解IList兼容阵列的一些实现,这些阵列以块的形式分配内存而不是一次性分配内存?这样可以避免我的内存碎片问题。
答案 0 :(得分:3)
Josh Williams在他的博客上使用分块数组提出了BigArray<T>
课程:
您将在此相关问题中找到更多有用的信息:
一个简单的临时修复可能是为您的应用程序启用3GB开关。这样做可以使您的应用程序使用超过32位Windows的每个进程限制2GB。但是,请注意CLR允许的最大对象大小仍为2GB。可以使用主可执行文件的后构建操作启用该开关:
call "$(DevEnvDir)..\tools\vsvars32.bat"
editbin.exe /LARGEADDRESSAWARE "$(TargetPath)"
答案 1 :(得分:1)
实例化数组时,.Net会尝试为您的数组找到连续的内存部分。由于32位应用程序的总内存限制为2Gb,因此您可以看到在多次分配后很难找到这样的块。
您可以尝试使用类似LinkedList<T>
的内容,以避免需要连续分配,或重新构建代码以使这些块更小(尽管您不会完全安全,这不会发生一个500Mb阵列也。)
另一方面,一种解决方案是在应用程序启动时仅将此大缓冲区实例化一次,然后实现一种算法,该算法将在应用程序的生命周期内重用相同的空间。
如果您可以使用IEnumerable而不是IList将数据传递给程序的其余部分,则可以使用SelectMany
LINQ方法折叠此列表。
最后,您可以在自定义类中简单地实现IList接口,并在引擎盖下使用几个较小的阵列。
答案 2 :(得分:0)
LinkedList会为你工作吗? http://msdn.microsoft.com/en-us/library/he2s3bh7.aspx