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

Mik*_*use 6 .net c# garbage-collection memory-leaks

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

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

内存使用率或多或少线性增加(如果我GC.Collect()在每天结束时强制执行一个非常顺利).

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

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

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

我正在研究这个问题中的参考文献.一般来说,我知道什么样的情况可能导致问题,我更感兴趣的是看看是否有更快的方法来识别具体细节而不花费宝贵的时间来完成我的代码勾选引用...

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

Mag*_*tLU 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[]
Run Code Online (Sandbox Code Playgroud)

从这个(已排序)输出,您可以告诉您有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
Run Code Online (Sandbox Code Playgroud)

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

!GCRoot 075d1000
Run Code Online (Sandbox Code Playgroud)

你会得到泄漏的原因.另外,您可能需要参考本教程.