.net - 如何让 .NET 取消提交未使用的 RAM?

标签 .net memory memory-leaks

以下是我的程序在极其密集地使用内存后的统计数据,在高峰期消耗了 6 GB,但随后将所有内容保存到磁盘并且几乎没有剩余空间:

Screenshot

观察到几乎所有东西都超出了范围并已被垃圾回收 - 堆大小很小。然而,.NET 保留了 181 MB已提交

我不介意保留字节,因为这只会消耗地址空间。但是提交的内存很烦人——即使它只驻留在页面文件中,它仍然很多。

最佳答案

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

这意味着您可以等待第 2 代垃圾回收自行发生,也可以使用 GC.Collect() 强制进行 - 您确实需要如果你选择这条路线,要知道你在做什么,但是因为它与垃圾收集器的标准垃圾收集周期相混淆,这真的会影响性能:

  • 完整的垃圾回收很慢,所以你真的不想太频繁地这样做
  • 比标准计划更频繁地触发垃圾回收会将其他对象提升到更高代,这意味着它们可能不会像通常那样被回收

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

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

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

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

When objects in generation 2 are collected, the CLR heap manager decommits memory in the segments, and when a segment is no longer needed, it is entirely freed.

关于.net - 如何让 .NET 取消提交未使用的 RAM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8212524/

相关文章:

c# - 如何在.Net WPF MVVM应用程序的ViewModel之间传递事件?

c# - Json DateTime 序列化在 DataContractJsonSerializer 和 System.Json 中是不同的

c# - 如何将以字符串命名的参数发送到存储过程?

c++ - C/C++ 如何清理系统/stdlib 调用分配的内存?

java - Eclipse Memory Analyzer - Leak Suspects Report 没有指向我的类 - 为什么?

c# - 所有 C# 强制转换都会导致装箱/拆箱

c++ - 试图在 Windows 7 上分配超过 2GB

flash - Flash Video Player的内存问题

c++ - 我是否需要shared_ptr 的删除器来释放分配器分配的内存?

objective-c - 解析 JSON 时内存使用率较高