我有一个处理多个步骤的过程。 (假设是一种策略模式的通用实现),其中所有步骤都在传递一个通用的ProcessParameter对象。 (对其进行读/写)
此ProcessParameter是一个具有许多数组和集合的对象。示例:
class ProcessParameter() {
public List<int> NumbersAllStepsNeed {get; set;}
public List<int> OhterNumbersAllStepsNeed {get; set;}
public List<double> SomeOtherData {get; set;}
public List<string> NeedThisToo {get; set;}
...
}
步骤完成后,我想确保释放内存而不是闲逛,因为这可能占用大量内存,并且其他进程也需要运行。
我可以通过运行以下命令来做到这一点:
pParams.NumbersAllStepsNeed = null;
pParams.OhterNumbersAllStepsNeed = null;
pParams.SomeOtherData = null;
...
或者ProcessParameter实现IDosposable,而Dispose方法可以做到这一点,那么我只需要使用pParams.Dispose()
(或将其包装在using块中)
清除一个正在运行的进程的已用数据的内存占用的最好,最优雅的方法是什么?
使用数组而不是列表会改变任何东西吗?还是混合? 我需要的实际参数类型是自定义对象的集合/数组。
我朝着正确的方向看吗?
更新
好问题!感谢您的评论! 我曾经让这个过程单次运行,我可以看到内存使用率很高,然后逐渐下降到“正常”。
当我开始使用不同的声明参数将这些进程彼此链接在一起时,问题就来了。那是内存过高的时候,所以我想在两个进程之间包括一个清理步骤,并寻找最佳的实现方法。
有一个数据库,这种参数是一种“缓存”,可以加快处理速度。
关于IDisposable的要点,我不在params对象中保留非托管资源。
答案 0 :(得分:1)
虽然使用Disposal模式是一个好主意,但我认为它在释放内存方面不会给您带来任何额外的好处。
可能有两件事:
但是,我真的不会打扰(除非您可能会遇到内存异常)。显式调用GC.Collect()可能会损害性能,并且垃圾回收器确实确实可以很好地完成工作。 (但请参见下面的LOH。)
您提到它使用了“大内存占用”。请注意,任何85,000字节或以上的单个内存分配都来自大对象堆(LOH)。 LOH不会像小对象堆那样被压缩。即使您有足够的可用内存,这也会导致LOH碎片化,并可能导致内存不足错误。
您何时会迷路到LOH?任何85,000字节或更多字节的内存分配,因此在64位系统上将是具有10,625个或更多元素的任何数组(或列表或字典),图像处理,大字符串等。
三种有助于最大程度地减少LOH碎片的策略:
i。重新设计以避免它。并不总是实用的。但是列表列表或词典可能会避免这种限制。这会使实施变得更加复杂,因此除非您确实需要,否则我不会这样做,但是从正面来看,这可能非常有效。
ii。使用固定尺寸。如果您在LOH中的所有其他内存分配都具有相同的大小,则这将有助于最大程度地减少碎片。例如,对于字典和列表,将容量(设置内部阵列的大小)设置为您可能使用的最大大小。如果您要进行图像处理,则不太实用。
iii。强制垃圾收集器压缩LOH:
start_date end_date value
1.0 2018-01-01 2018-01-31 17
您确实需要使用.NET Framework 4.5.1或更高版本才能使用它。 这可能是最简单的方法。在我自己的应用程序中,我有几个实例,我知道我会迷路到LOH中,而碎片化可能是一个问题,我设置了
System.Runtime.GCSettings.LargeObjectHeapCompactionMode = System.Runtime.GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
作为析构函数中的标准-但只有在分配时遇到内存不足异常时,才显式调用GC.Collect()。
希望这会有所帮助。