我有一个庞大的网站,似乎正在吸掉分配的所有内存。除了这个网站以外,服务器上没有其他东西。一周之内,它会耗尽2GB内存并需要重新启动。当前使用的是Server 2008 32位操作系统,使用IIS 7。我们将重新安装64位操作系统并添加更多内存。能够追踪泄漏发生的位置将非常有帮助。
那么,追踪内存泄漏的最佳实践是什么呢?
我有一个庞大的网站,似乎正在吸掉分配的所有内存。除了这个网站以外,服务器上没有其他东西。一周之内,它会耗尽2GB内存并需要重新启动。当前使用的是Server 2008 32位操作系统,使用IIS 7。我们将重新安装64位操作系统并添加更多内存。能够追踪泄漏发生的位置将非常有帮助。
那么,追踪内存泄漏的最佳实践是什么呢?
.NET 中的内存泄漏不常见,但当它们发生时,最常见的原因是未附加事件处理程序。确保在监听器超出作用域之前分离处理程序。
另一种可能的原因是忘记在 IDisposable
资源上调用 Dispose()
。这可能会阻止对未托管资源(GC 不处理的资源)的清理。
还有一个可能的原因是死锁的终结器。这将防止队列中所有剩余的对象被收集。
我使用 WinDbg + Sos 来跟踪内存泄漏。步骤如下:
!gcroot
找出是什么使可疑项保持活动状态请注意,大量的内存使用也可能是由于堆碎片化引起的。常规堆是紧凑的,但固定对象可能导致碎片化。此外,LOH 不是紧凑的,所以 LOH 的碎片化很常见。
WinDbg + sos 的优秀教程位于此处:http://blogs.msdn.com/tess/
监控应用程序
有关要监视什么的想法,请参见Improving .NET Performance and Scalability,特别是第15章。
至于如何监视,也有商业工具可用,但是,每台Windows机器也都配备了Perfmon.exe,可用于记录相关性能计数器。
测试应用程序
如果想了解如何执行负载或压力测试,请查看模式和实践Web应用程序性能测试指南。
调试应用程序
一旦您确定存在问题(监控)并且能够重现问题(测试),就可以开始调试问题。请参阅Tess的链接 - 这些信息将帮助您很长一段时间。
然后反复进行! :)
祝你好运!
Z
你可以尝试使用像 dotTrace 这样的分析工具 -- 将其设置为内存跟踪模式并运行你的应用程序。
这应该会给你一些线索,让你知道哪些程序集和应用程序区域在启动时占用了过多的内存。
这可能更多是预防而不是检测,但在 C# 代码层面上,您应该检查任何使用大量资源(如图像和其他文件)的类是否正确实现了dispose 模式。如果需要,您还可以覆盖终结器。
MSDN 对此有很好的指导。
如果您的应用程序中有任何使用大量资源的类,这些都是查找内存问题的第一处地方。