在显式调用GC之前,应用程序不会释放内存

时间:2012-02-01 23:18:16

标签: c# garbage-collection

我同时启动多个线程,每个线程都在队列中写入/读取数据;数据在处理并存储到DB时逐步出列。出于某种原因,内存未被释放虽然队列是空的,但我确保数据读取器和数据处理器之间的所有事件订阅都在线程末尾取消订阅。蹲下的RAM 完全二进制读取器读取的数据量并放入队列中。

为了隔离问题,我绕过了Processing和DB Storing步骤。
为什么在所有线程完成后,RAM仍然会被蹲,直到我明确地调用GC.Collect()或终止程序?我在清空后手动使队列无效,并且还使读取数据的二进制读取器无效。我认为这足以让GC至少在几分钟后醒来并做家务。

enter image description here

编辑: (删除后重新制定)问题: 简而言之,我总是被告知默认的GC行为正确地管理了内存,我几乎从不会明确地调用GC并让框架完成工作。
我想知道为什么在这种情况下,只有在对GC.Collect进行显式调用时,内存使用量才会下降

编辑:
没有GC收集

enter image description here

使用GC Collect (定期调用) enter image description here

3 个答案:

答案 0 :(得分:4)

可能发生垃圾收集有三种情况(参见MSDN):

  

1。)系统物理内存较低。

     

2.。)托管堆上已分配对象使用的内存   超过可接受的门槛。这意味着一个门槛   托管堆上已超出可接受的内存使用量。这个   随着过程的进行,阈值会不断调整。

     

3.)调用GC.Collect方法。在几乎所有情况下,你都没有   调用此方法,因为垃圾收集器连续运行。   此方法主要用于独特的情况和测试。

根据你的描述,听起来框架决定1.)和2.)是这样的,因此它只会在你拨打GC.Collect()时收集

答案 1 :(得分:1)

根据屏幕截图,在整个应用程序运行期间,您的内存使用率似乎永远不会超过50%。为了收集垃圾,.NET框架单独留下内存比停止应用程序(或者至少占用大量CPU时间来检查活动)要快得多。如果你将机器的RAM削减到2 GB左右,我确信垃圾收集器会升级并将内存使用量保持在硬件限制范围内。

答案 2 :(得分:1)

您似乎在泄漏对象,应该使用windbg创建转储,然后使用sos.dll跟踪对象的根目录。

您可以按照此explanation了解如何跟踪对象的“根”,并查看造成这些泄漏的原因。