在c#中显式释放内存

Chr*_*ris 37 .net c# memory profiling memory-leaks

我创建了一个使用150mb内存(私有字节)的ac#应用程序,主要是因为一个很大的字典:

Dictionary<string, int> Txns = new Dictionary<string, int>();
Run Code Online (Sandbox Code Playgroud)

我想知道如何释放这个记忆.我试过这个:

Txns = null;
GC.Collect();
Run Code Online (Sandbox Code Playgroud)

但它似乎并没有对我的私人字节造成太大影响 - 他们从155mb减少到145mb.有线索吗?

谢谢

-编辑-

好吧,我对这段代码运气不错(它将私有字节减少到50mb),但为什么呢?

Txns.Clear(); // <- makes all the difference
Txns = null;
GC.Collect();
Run Code Online (Sandbox Code Playgroud)

-编辑-

对于那些说'不要使用GC.collect'的人来说,这是公平的(我不打算辩论,除了说你可以看到我的C背景通过),但它并没有真正回答我的问题:如果我先清除事务列表,为什么垃圾收集器只释放内存?它不应该释放内存,因为字典已被解除引用?

Bri*_*sen 18

专用字节反映了进程的内存使用情况.当收集对象时,相关的存储器段可以或可以不被释放到OS.CLR管理操作系统级别的内存,并且由于分配和释放内存不是免费的,因此没有理由立即释放每个内存,因为应用程序可能会在以后请求更多内存.

  • 关键是,在托管应用程序中,您只需一步就可以直接处理操作系统内存,因为CLR会为您执行此操作.您可以构建可以在描述时观察直接影响的场景,但这并不能保证您可以根据CLR的实现细节进行操作. (3认同)
  • 这一切听起来都很合理,但如果我调用Txns.Clear(),它确实会将内存释放到操作系统中.另外,我真的很想对操作系统内存感觉很好,因为我不是唯一一个使用这个服务器的人. (2认同)
  • 我想我要问的是,为什么txns.Clear()会将内存返回给操作系统,当引用整个字典时不会将其返回? (2认同)

Sad*_*egh 11

如果你调用GC.Collect()它开始做它的工作,但它立即返回,它没有阻止,所以你没有看到它的影响,如果你只是调用GC.WaitForPendingFinalizers()之后它会阻止你的应用程序直到GC. Collect()完成它的工作

  • @peSHIr:同意,虽然公平地说,它明确回答了这个问题.是否一个好主意是一个不同的问题. (9认同)

Dav*_*itt 5

很可能你在其他地方有一个隐藏的字典引用.因此,不收集字典,但如果你收集,则Clear()收集内容.

正如其他人已经指出的那样,不推荐强制使用GC.这可能导致内存被推入更高的"世代",这些世代通常不被收集,从而浪费的内存比从长远来看更多.