如何让.NET取消使用未使用的RAM?

时间:2011-11-21 13:24:54

标签: .net memory memory-leaks

以下是我的程序在使用内存非常密集,在其峰值时消耗6 GB,但随后将所有内容保存到磁盘并且在范围内留下的内容时的统计信息:

Screenshot

观察到几乎所有内容都已超出范围并且已被垃圾收集 - 堆大小很小。然而,.NET保持181 MB 提交

我不介意保留字节,因为它只占用地址空间。但是承诺的内存很烦人 - 即使它只存在于页面文件中,它仍然存在很多。

1 个答案:

答案 0 :(得分:7)

根据CLR Inside Out - Large Object Heap Uncovered,CLR在Gen 2垃圾收集期间解除未使用的已提交内存。

这意味着您可以等待Gen 2垃圾收集单独发生,也可以使用GC.Collect()强制进行 - 你真的需要知道你在做什么你选择这条路线,因为它与垃圾收集器标准的垃圾收集周期混淆,这可能真的搞乱性能:

  • 完整的垃圾收集很慢,所以你真的不想经常这样做
  • 比标准时间表更频繁地触发垃圾收集会将其他对象提升到更高代,这意味着它们可能无法在通常情况下立即收集

据我所知(从我相当有限的研究中),CLR不会在其他情况下释放已提交的内存。

您还应该考虑这是否真的是一个问题:

  • 如果您的进程将立即继续执行额外的内存密集型处理,那么它将很快再次需要该内存,因此无论如何都不会大量减少内存的好处
  • 如果您已完成处理并将很快终止,则无论如何都将取消内存
  • 无论如何都没有必要提交大量内存 - 是的,这意味着内存分配了后备存储,但是如果系统处于内存压力之下,那么后备存储很可能是无论如何都是一个页面文件。

更新: Advanced .NET Debugging: Managed Heap and Garbage Collection似乎支持这样的假设:内存仅在第2代/完整集合期间未提交:

  

当收集第2代中的对象时,CLR堆管理器会解除段中的内存,并且当不再需要某个段时,它将被完全释放。