我有一个大型网站似乎正在吸收正在分配的所有内存。此站点旁边的服务器上没有其他任何内容。在一周内,它会吃掉2场演出并需要重新启动。目前这是使用IIS 7的服务器2008 32位。我们重新安装使用64位并添加更多内存。能够追踪泄漏发生的位置会很好。
那么跟踪内存泄漏的最佳做法是什么?
答案 0 :(得分:14)
.NET中的内存泄漏并不常见,但是当它们发生时,最常见的原因是未连接的事件处理程序。在侦听器超出范围之前,请确保分离处理程序。
另一种选择是忘记在Dispose()
资源上致电IDisposable
。这可能会阻止清理非托管资源(不由GC处理)。
另一个可能的原因是一个僵局的终结者。这将阻止收集终结器队列中的所有剩余对象。
我使用WinDbg + Sos来追踪泄漏。步骤如下
!gcroot
找出让嫌犯活着的原因请注意,大量内存使用也可能是由于堆碎片造成的。常规堆是压缩的,但固定的对象可能会导致碎片。此外,LOH没有压实,所以LOH并不罕见。
关于WinDbg + sos的优秀教程:http://blogs.msdn.com/tess/
答案 1 :(得分:9)
答案 2 :(得分:4)
跑步,不要走路,走到苔丝身边 Ferrandez的博客If broken it is, fix it you should,很好 专门用于学习的脚本实验室 如何诊断和调试崩溃,挂起 和.NET代码的内存问题。她 有一些我最好的材料 迄今为止找到了帮助你入门。
商业内存分析器(例如ANTS和SciTech)是极好的资源,可以显示堆中的对象以及它们的根源。大多数商业内存分析器都能够加载进程的内存“快照”(例如,从您的生产环境中)。
您可以使用adplus.vbs或Snap v. Dump捕获内存“快照”(请参阅DebugDiag)。 Adplus作为Debugging Tools for Windows的一部分提供。 DebugDiag还将自动进行一些基本的分析(但在非托管代码上似乎更可靠)。
监控应用
有关监控内容的想法,请参阅Improving .NET Performance and Scalability,特别是第15章。
关于如何监控,也有可用的商业工具,但是,每台Windows机器都附带Perfmon.exe,可用于记录相关的性能计数器。
测试应用
有关如何执行负载或压力测试的想法,请查看模式和实践Performance Testing Guidance for Web Applications。
调试应用程序
一旦你发现你遇到问题(监控)并且能够重现问题(测试),你就可以开始调试问题。查看苔丝的链接 - 这些信息将为您带来很长的路要走。
然后冲洗并重复! :)
祝你好运!答案 3 :(得分:3)
在性能监视器中,为所有堆中的进程/专用字节和.NET CLR内存/#字节添加计数器。专用字节是所有内存,CLR内存只是管理。因此,如果CLR内存保持相当均匀,但私有字节会随着时间的推移而持续增长,这意味着泄漏位于非托管资源中。这通常意味着您没有正确处理本机资源。好看的是COM或IO(流和文件)之类的东西。完成后,确保所有这些东西都被处理掉了。
答案 4 :(得分:1)
您可以尝试使用dotTrace等分析器 - 将其设置为内存跟踪并运行您的应用程序。
这应该可以为您提供线索,其中应用程序的程序集和区域在开始时会占用太多内存。
答案 5 :(得分:1)
这可能是预防而不是检测,但在c#代码级别,您应该检查使用大型资源(如图像和其他文件)的任何类是否正确实现the dispose pattern。如果需要,您可能还需要覆盖终结器。
MSDN对此主题有很好的指导。
如果您的应用程序中有任何您知道使用大量资源的类,那么这些是第一个查找内存问题的地方。
答案 6 :(得分:1)
我发现EQATEC Profiler非常好,而且它是免费的!
答案 7 :(得分:1)
在此博客文章中查看内存和内存泄漏实验:
他们可能会有所帮助。基本上,您可以使用WinDBG来分析内存转储,并帮助确定占用所有内存的内容。
我们使用类似的方法来确定Regex正在咀嚼我们所有的内存,但只有当产品在64位计算机上运行时才会这样。学习曲线有点陡峭,但WinDBG是一个非常强大的工具。
答案 8 :(得分:1)
答案 9 :(得分:0)
你做任何Office互操作吗?如果是这样,请确保清理应用程序对象。这是一个可能的罪魁祸首。
另一个是全局对象,例如任何静态的对象。
答案 10 :(得分:0)
答案 11 :(得分:0)
查看页面底部提到的this article on detecting .NET application memory leaks及相关文章,希望您能找到解决方案,或者至少有一个想法来解决它。
由于