我的(C#.NET 4.0)应用程序运行一段时间,根据从sqlite数据库获取的价格变化更新模拟帐户.
我在任何特定日期都需要的是当前状态的帐户和最新价格.我希望垃圾收集器能够将内存使用率保持在一个相当均匀的龙骨上:我所看到的是工作集和私有内存(由System.Diagnostics.GetCurrentProcess()报告)以及GC中的稳定增长. GetTotalMemory(true):在这种情况下每天约300K.不可避免地,整个事情在大约12个模拟年后崩溃,此时内存使用量增加了大约1GB.
内存使用率或多或少线性增加(如果我在每天结束时强制GC.Collect(),则会非常顺利).
我推断一些对象在某种程度上不是垃圾收集的,即使我认为它们不再需要它们并且预期它们会在正常的退潮和执行流程中被清理干净.
我可以尝试确定哪些地方无意中造成了这种情况?
我已经下载并运行了CLRProfiler – 它将在周末最好的部分消化文档,但并不能保证它能够提供帮助.
我正在研究this question中的参考文献.总的来说,我知道什么样的情况可能导致问题,我更感兴趣的是看看是否有更快的方法来识别细节而不花费宝贵的时间来处理我的代码滴答作响关于引用…
注意:问题似乎与事件无关,并且不涉及图形组件.
解决方法
您说您可以模拟工作负载以导致应用程序崩溃.要快速查找泄漏,请模拟工作负载,直到内存消耗变得很大(例如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.