我经常调用HttpHandler
。它使用Entity Framework
来完成任务。
此Web应用程序的w3p.exe
使用内存缓慢增加(它有一个单独的应用程序池)。我使用ANTS memory profiler
并且那里有很多空闲内存(LOH)。 ANTS
表示这些是GC root
个对象。我检查了我的代码,但有一些int
和string
无法导致LOH
!
我追踪了泄漏的来源,但遗憾的是它的类型System.Object
具有很多null
属性。还有一个LinkedList
,一些HashTable
和一个WeakHashTable
。
如何找到此对象的内容并修复LOH
?如何true
IsReusable
返回HttpHandler
?
答案 0 :(得分:1)
首先,你必须追踪实际发生的事情。在这种情况下,我的第一个工具总是 WinDbg。
http://www.windbg.org/ http://en.wikipedia.org/wiki/WinDbg
要将其与托管/ .NET代码一起使用,您需要使用SOS(Son of Strike)扩展名:
http://msdn.microsoft.com/en-us/library/bb190764.aspx
http://blogs.msdn.com/b/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx
所以,一旦你将WinDbg附加到你的w3wp.exe进程中,你要做的第一件事就是弄清楚堆中的实际内容:
!dumpheap -stat
这将为您提供内存中所有当前“实时”对象的格式良好的视图,以及它们中有多少,它们占用的字节数,按对象类型分组。
现在,大对象堆(LOH) - 通常,当对象被垃圾收集时,会发生压缩,就像对硬盘进行碎片整理一样。这样可以快速有效地为新对象分配。问题是,大型物体不易于压缩 - 一切都必须四处移动才能容纳它们。因此,任何占用超过85000字节的内容都会被困在一个称为大对象堆的特殊位置。这个堆不是压缩的,所以随着时间的推移,很像硬盘驱动器,会发生碎片,在堆中留下未使用的间隙,这会导致运行时需要更多的空间等等。
那么,让我们问一下windbg告诉我们LOH中的内容:
!dumpheap -stat -min 85000
这将显示大对象堆中的实际内容 - 其中一些对象可能会向您跳出,如List或MyClass []。
重要提示:如果您在大对象堆中看到的内容故意长期存在(例如,记录器的静态实例),则可能不是真正的问题。但是,您确实希望尝试减少那里短暂/经常创建的对象的数量,以减少碎片。
所以,我推荐一份SOS探索备忘单:
http://windbg.info/doc/1-common-cmds.html
http://windbg.info/doc/2-windbg-a-z.html
有趣的命令:
!gcroot <address> <- will show you what object is "rooting" another
!CLRStack <- show current managed call stack
!dumpobj <address> <- show information about object at address
但我最喜欢的是:
bp clr!SVR::gc_heap::allocate_large_object "!CLRStack; g;"
它在CLR在大对象堆上分配对象时使用的实际内部调用设置断点,当命中时,将转储完整的堆栈跟踪,然后继续。