C#中大型列表如何使用可用内存?

Esn*_*der 25 c# garbage-collection list

我有一个名单Population,是很多位置的很好的列表,在某些时候我停止使用它.我如何释放资源?那么这是代码的一部分:

 private List <BasePopulation> Population=new List <BasePopulation>();
 Population.SomeMethod();
 Population.Clear();
Run Code Online (Sandbox Code Playgroud)

我使用了Clear方法,但没有用.任何的想法?

Bri*_*eon 31

问题可能在于Clear没有按照您的想法进行.Clear只需将其标记List为空,而不调整其在幕后使用的内部数组的大小.但是,它将删除对各个BasePopulation实例的所有引用.因此,如果没有其他数据结构可以引用它们,则它们将有资格进行垃圾回收.但是,它不会List直接减小尺寸.我刚用ILSpy验证了这一点.

你有两个选择.

  1. 设置Population = null.这将取消整个对象实例的根目录,使其符合垃圾回收的条件.

  2. 呼吁TrimExcess这个List.这将调整内部数组的大小.

  • @Pierre-LucPineault:你是对的。好吧,除了 **local** 引用。对于问题中的 **class member** 引用,垃圾收集器无法执行相同的优化,因为很难(或可能)预测将来是否会读取它。 (3认同)

big*_*gge 7

好吧,既然垃圾收集器(GC)正在为你处理内存管理,你可以做的第一件事是删除列表的所有引用(以及包含的元素),以便GC能够删除它下一次.例如,您可以通过显式设置来执行此操作

Population = null;
Run Code Online (Sandbox Code Playgroud)

如果因为你这是不够的,你的,例如真正渴望摆脱对象的现在 可以接受非最佳运行时的行为,你可以告诉GC开始收集对象现在通过

GC.Collect();
Run Code Online (Sandbox Code Playgroud)

有关此方法的更多信息,请参见此处.

如上所述,这种做法可能会导致性能下降,因为它会强制GC在程序中通常不会清理资源.因此通常不鼓励直接调用该方法,但如果这是您应用程序中的特殊点,它可能会满足您的需求.作为一个实际例子,我成功地改进了一个程序中的峰值内存使用,该程序在初始化期间需要大量对象,一旦实际程序执行开始就可以丢弃.这里,GC.Collect()初始化后调用的性能损失很小是合理的.

  • 我读过"人口=空;"可能会让事情变得更糟.它构成了对"人口"的引用,因此将GC推迟到该引用之后.你最好什么都不做. (2认同)