【发布时间】:2018-08-23 13:41:36
【问题描述】:
我有一个流程需要多个步骤。 (假设是策略模式的通用实现)所有步骤都在传递一个通用的 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()(或将其包装在使用块中)
清理一个正在运行的进程的已用数据的内存占用的最佳和最优雅的方法是什么?
使用数组而不是列表会改变什么吗?还是混合的? 我需要的实际参数类型是自定义对象的集合/数组。
我的方向是否正确?
更新
好问题!感谢cmets! 我曾经让这个进程单独运行,我可以看到内存使用率非常高,然后逐渐下降到“正常”。
当我开始使用不同的声明参数将这些进程链接在一起时,问题就出现了。那是内存异常高的时候,所以我想在两个进程之间包含一个清理步骤,并寻找最好的方法来做到这一点。
有一个数据库,这个参数是一种“缓存”来加快速度。
关于 IDisposable 的要点是,我不会在 params 对象中保留非托管资源。
【问题讨论】:
-
您是在尝试解决实际问题还是在询问如何实施过早优化?
-
IDisposable用于释放非托管资源。要使托管对象符合 GC 条件,您只需要确保没有对它的引用。另见What is the correct way to free memory in C# -
一旦
ProcessParameter不再可访问并被收集,其属性中包含的所有对象也将被收集。一般来说,除非您使用ProcessParameter实例的时间比子对象长得多,否则不需要显式地null它们。如果有这样的需求,你应该在诉诸半手动内存管理恶作剧之前认真考虑拆分对象。对于初学者来说,这样的事情是NullReferenceException等待发生的事故。 -
我同意杰罗恩的观点。 “使用”不会有任何帮助,我想从您给出的使用描述推断,生命周期不会在一个“使用”块内处理。我想补充一点,你可能应该小心不要“泄露”引用,所以那些大的引用可以被 GC 回收,仅此而已。你应该没事。
-
如果不涉及非托管资源,可能 GC.Collect 和 GC.WaitForPendingFinalizers 是您要查找的,而不是 Dispose。然而,在大多数情况下,这样的 hack 是没有用的......
标签: c# memory-management idisposable