我知道我的问题没有简单的答案,但我会很感激想法,指南或者 某种事情看待清单
我有一个不断抛出OutOfMemoryException的网络Windows服务。 该服务有两个用于x86和x64 Windows的版本。但是在x64上它会消耗更多 记忆。我尝试使用各种内存分析器对其进行分析。但我无法弄清楚问题是什么。诊断 - 服务消耗了大量的VMSize并在3到12小时后崩溃应用程序。行为是相当随机的 - 崩溃情景没有可观察的模式。
另外,我试着看一下性能计数器(perfmon.exe)。我能看到的是 堆大小正在增长,%GC时间平均为19%。内存分配与%CPU时间相关。
我的应用程序有线程和锁定对象,数据库连接和WCF接口。 我想解决的一般性问题:
仅仅GC还不够快 到GC对象或一些非托管 (windows)对象正在消耗 存储器?
查看列表中的第一个应用 http://s45.radikal.ru/i109/1003/af/92a389d189e8.jpg http://s45.radikal.ru/i109/1003/af/92a389d189e8.jpg
带有性能计数器视图的图片链接 http://s006.radikal.ru/i215/1003/0b/ddb3d6c80809.jpg
答案 0 :(得分:7)
你的问题是你不知道消耗大量内存的是什么?当进程使用大量内存时,您可以打开任务管理器,右键单击您的进程并创建一个转储文件,您可以在windbg中检查该文件以确切了解分配内存的内容。
Tess Ferrandez有很多优秀的演示。 She goes through the most useful stuff here...
答案 1 :(得分:4)
您的问题很可能是经典泄漏(当它们不应该存在时仍然生根的对象)或大对象堆(LOH)碎片。
我发现用于诊断此类问题的最佳工具是Windows调试器的Son of Strike(SOS)扩展。下载Microsoft的Debugging Tools for Windows以获取调试器:CDB是控制台调试器(我更喜欢它,因为它似乎响应更快),WinDbg与MDI应用程序包装相同。这些工具水平较低,有一些学习曲线,但提供了解决问题所需的一切。
特别是,运行!DumpHeap -stat
以查看哪些类型的对象正在占用您的记忆。如果注意到任何重大碎片,此命令也将在列表底部报告。 !EEHeap
将列出堆段 - 如果有很多LOH段,那么我会怀疑LOH碎片。
0:000> .loadby sos mscorwks 0:000> !EEHeap -gc Number of GC Heaps: 1 generation 0 starts at 0x00f7a9b0 generation 1 starts at 0x00e79c3c generation 2 starts at 0x00b21000 ephemeral segment allocation context: none segment begin allocated size 00b20000 00b21000 010029bc 0x004e19bc(5118396) Large object heap starts at 0x01b21000 segment begin allocated size 01b20000 01b21000 01b8ade0 0x00069de0(433632)
如果有很多LOH段,那么我会开始怀疑LOH碎片。
然而,在此之前,我有兴趣知道:
(我之所以这样说是因为1. .NET字符串实习表的实现方式可能会导致LOH碎片化,而事件订阅会为订阅对象提供额外的根,这很容易被遗忘。)
答案 2 :(得分:3)
我使用.Net Memory Profiler比使用microsoft的clr profiler好得多。你必须要了解一点。它可以告诉您哪个对象没有处理或有引用。您还可以根据类型和内存对对象进行排序。我使用了最近30天的试用版,在此期间我能够在我的申请中解决问题。
答案 3 :(得分:1)
如果您在GC上花费的百分比时间很长,那么我会看看LOH Allocations perfmon counter。如果在LOH中频繁分配,这将导致GC努力收集,这是GC花费高百分比时间的原因。
我做了关于identifying high CPU in GC because of LOH的博客,其中显示了如何获得在LOH中分配的确切调用堆栈。
希望这会有所帮助。