确定GC.Collect()收集的内容

时间:2017-12-09 22:14:51

标签: c# .net vb.net

我有一个用VB.NET(.NET 4.5.2)编写的控制台程序,它充当服务。连续循环运行,然后等待MSMQ队列上的消息,并处理该消息。不知何故,这个程序有很大的内存泄漏。我已经完成了所有代码,并尽我所能使用Using语句,但问题仍然存在。循环次数越多,程序使用的内存越多,垃圾收集器就不会回收这个内存。

我最终在循环的底部放置了一个GC.Collect(),并且能够释放大部分内存。但是,我意识到这是不好的做法,可能会导致问题。只是想知道是否有办法检查GC.Collect()摆脱了哪些变量,所以我可以找到问题的根源?

Do While (True)
    ' Code to wait for message on a queue
    ' Code to process message (includes calls to class library)
    GC.Collect()
Loop

1 个答案:

答案 0 :(得分:2)

如果垃圾收集器在手动调用时释放内存,则不会泄漏内存。托管内存环境中的泄漏是GC无法释放的内存,因为它在对象图上的某处被引用。

可能是他们的代码使用了被提升为gen1,gen2或大对象堆的对象实例。这些世代的实例收集频率低于gen0。 Windows资源监视器包含许多performance counters that can be used to profile the behavior of the managed heap。我猜你可能有对象被提升为gen2。跟踪“Gen 1 Promoted Bytes / Sec”计数器可以让您了解这是否正在发生。

在托管内存环境中,GC在存在内存压力时运行,而不是在不再需要对象实例时运行,因此仅增加内存使用量并不一定是泄漏的迹象。

如果你取出Collect,内存使用总是会增加(比如几分钟或队列中正在处理的消息),还是上下有点像一个浪潮?如果是后者只是让GC做它的事情,你就没有泄漏。