从C#中的大型数据结构中释放内存

Dim*_*ris 5 c# data-structures

我有几个SortedList<>SortedDictionary<>结构,我的模拟代码和我在他们随着时间的推移增加数以百万计的项目。问题在于,垃圾回收器无法快速释放足够的内存,因此会对应用程序的性能造成巨大影响。我的最后一个选择是使用该GC.Collect()方法,以便我可以收回该内存。有人有不同的想法吗?我知道Flyweight模式是另一种选择,但是我希望其他建议不需要大量重构我的代码。

Han*_*ant 5

您正在与“没有免费午餐”的原则作斗争。您不能假设在列表中填充数百万个项目不会影响性能。只有SortedList <>应该是一个问题,它将开始在大对象堆中分配内存。该分配不会很快被释放,需要第二代收集才能再次将这些东西从LOH中剔除。否则,此延迟不应影响程序的性能。

您可以做的一件事就是避免内部数组的多个副本,当SortedList <>不断增长时,它会塞入LOH中。尝试为Capacity猜测一个不错的值,以便它预先分配大型数组。

接下来,使用Perfmon.exe或TaskMgr.exe并查看程序的页面错误增量。分配时应该很忙。如果看到较低的值(小于或等于100),则可能是页面文件碎片化的问题。在运行XP的旧计算机上常见的祸害。对磁盘进行碎片整理并使用SysInternals的PageDefrag实用程序可以产生非凡的成就。


wil*_*lem 4

我认为SortedList使用数组作为支持字段,这意味着SortedList在大型对象堆上分配了大型。大对象堆可能会进行碎片整理,这可能会导致内存不足异常,而原则上仍然有足够的可用内存。
请参阅此链接

这可能是您的问题,因为对 GC.collect 的中间调用可防止 LOH 在某些情况下进行严重碎片整理,这解释了为什么调用它可以帮助您减少问题。

通过将大对象分割成更小的片段可以缓解这个问题。