2011-08-16 191 views
2

我在.net中有一个应用程序,它获得的内存越来越多。 我从团队成员那里得到了一些关于我的应用程序分配的最常见和最重的实例的分析。.net内存泄漏问题

enter image description here

的问题是,我不知道下一步该怎么做。 源代码是巨大的! 和我需要最佳实践如何捕获有问题的函数/代码行。

p.s-我试过使用visual studio的“.net内存分配(采样)”功能,但它总是无法创建报告。 (猜猜这可能是另一个问题)。

+0

顺便说一句,你正在使用Visual Studio的哪个版本? – sll

+0

visual studio 2010 – Erez

回答

1

Visual Studio Profiler完全符合您的要求,它能够在调用堆栈中显示热路径。您必须学习如何使用Profiler,因此如果您无法生成Visual Studio Profiler报告并且无法调查如何执行此操作,则首先应该阅读文档,因为无论您使用的是哪种工具。

下面是关于Visual Studio的分析器有用的链接:

编辑:热路径通过VS探查:

0

我最喜欢做的第一件事就是使用windbg和psscor2。 然后我做了!gcroot和/或!GCRef。这个有时提供洞察保持对象活着的基础引用。

对不起该冲的回答,请例如this blog一些更多的参考,如果你不知道psscor2

0

如果我没有记错的话,它看起来像你的队友已经在使用的WinDbg与托管扩展(也许是SOS?),并且打电话给!dumpheap -stat。获取他的内存转储文件的副本,在WinDbg中打开并加载SOS。

第一步是深入研究特定的类型。就你而言,它看起来像你有一个非常大的字符串分配(大约84MB)。因此,尝试通过运行看字符串列表:

!dumpheap -type System.String 

它将输出字符串实例的名单。输出会是这个样子:

Address MT   Size Gen 
0x412d0030 0x79b94638 812 1 System.String XXXX 
0x422d0030 0x79b94638 812 1 System.String XXXX 
0x432d0030 0x79b94638 812 1 System.String XXXX 

该命令可能会几分钟运行,因为你有很多字符串实例,但尝试观察,而其运行的输出。如果您注意到很多实例具有相同的大小,那通常表明您没有正确地释放资源。任何这些实例都是下一步的理想选择。如果在列表的末尾还可以看到大尺寸的字符串,这些也是下一步的好选择。

下一步是检查哪些对象正在引用特定的字符串实例并阻止它被垃圾收集。您可以通过使用从dumpheap输出地址上方,然后调用做到这一点:

!gcroot 0x432d0030 

这将输出类似这样:

173866dc(System.Web.UI.WebControls.ListItemCollection)-> 
173866ec(System.Collections.ArrayList)-> 
173894b8(System.Object[])-> 
17386d0c(System.Web.UI.WebControls.ListItem)-> 
17386ce8(System.String) 

你可以阅读从底部到顶部。所以在这个例子中,字符串保存,该列表项目又由对象保存。在这一点上,解决你的问题变得更加艺术。从该链的底部开始(包括字符串),并且对于每一行上行,请检查是否可以将该对象存储在内存中。如果没有,那么你应该找到一种方法来释放该资源并将其收集起来。这一步很可能会要求您查看和分析每个课程的代码。

提示:由于System.Action的实例数量异常多,因此很有可能订阅了事件/多播委托,并且之后忘记取消订阅。