我如何识别未被垃圾收集的不需要的.NET对象?

时间:2011-12-02 16:11:15

标签: c# .net memory-leaks garbage-collection

My(C#.NET 4.0)应用程序运行一段时间,根据从SQLite数据库获取的价格变化更新模拟帐户。

我在任何特定日期需要的是当前状态的帐户和最新价格。我希望垃圾收集器可以将内存使用率保持在一个相当均匀的龙骨上:我看到的是工作集和私有内存(由System.Diagnostics.GetCurrentProcess()报告)和{{1}中的稳定增长}:在这种情况下每天约300K。不可避免地,整个事情在大约12个模拟年后崩溃,此时内存使用量增加了大约1GB。

内存使用率或多或少线性增加(如果我在每天结束时强制GC.GetTotalMemory(true),则会非常顺利)。

我推断一些对象在某种程度上不是垃圾收集的,即使我认为对它们没有进一步的需要,并且预计它们会在正常的退潮和执行流程中被清理干净。

我可以尝试确定哪些地方无意中造成了这种情况?

我已经下载并运行了CLRProfiler - 它会花费周末的最佳时间来消化文档,并且无法保证它能够提供帮助。

我正在研究this question中的参考资料。一般来说,我知道什么样的情况可能会导致问题,我更感兴趣的是看看是否有更快的方法来识别细节,而不花费宝贵的时间来处理我的代码,勾选参考文献......

注意:问题似乎与事件无关,并且没有涉及图形组件。

3 个答案:

答案 0 :(得分:7)

您说您可以模拟工作负载以导致应用程序崩溃。要快速查找泄漏,请模拟工作负载,直到内存消耗变得很大(例如100 MB),将WinDbg或VS与非托管调试连接到您的进程并立即运行:

.load sos
extension C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll loaded
!dumpheap -stat
total 2885 objects
Statistics:
MT    Count    TotalSize Class Name
7a5eab18        1           12 System.Diagnostics.TraceOptions
(lots of unimportant stuff here)
79332b54      304         7296 System.Collections.ArrayList
79333274       56        11640 System.Collections.Hashtable+bucket[]
793042f4      345        50056 System.Object[]
79330b24     1041        99428 System.String
79332cc0       21    107109728 System.Int32[]

从此(已排序)输出中,您可以告诉您int[]类型存在问题。类型:

!DumpHeap -type System.Int32[] (or whichever type you got)
Address       MT     Size
01381a1c 7931e9bc       40     
(cut)
075d1000 79332cc0 67108880     
03811000 79332cc0 40000016     
total 22 objects
Statistics:
MT    Count    TotalSize Class Name
7931e9bc        1           40 System.Int32[][]
79332cc0       21    107109728 System.Int32[]
Total 22 objects

现在您拥有对象的地址。选择其中一个并运行

!GCRoot 075d1000

你会得到泄漏的原因。另外,您可能需要咨询this tutorial

答案 1 :(得分:3)

你在使用活动吗?如果对象A订阅了对象B上的事件,则B正在存储对A的引用。因此,在A可以进行垃圾回收之前,不能对B进行垃圾回收。如果A取消订阅B,则会移除BA的引用。

答案 2 :(得分:2)

我建议将其作为一种启发式方法寻找的东西是你可能在一个较长寿的实例中附加一个事件的地方。如果你有一些实例在你的应用程序的生命周期中坚持下去,并且你有较短的生活类来监听它上面的事件,那么如果不解开这些事件将导致垃圾收集器跳过你的短生命对象,因为更长寿的物体挂在它们的引用上,直到你分开。

编辑:对于它的价值,你可能想看看Ants Memory Profiler。我不知道它与你正在看的那个相比如何,但是从试过它之后,它的学习曲线也不算太差,所以你可能花更少的时间搞清楚它。