【问题标题】:MVC3 memory managementMVC3 内存管理
【发布时间】:2012-02-23 07:28:52
【问题描述】:
在 ASP.NET MVC3 应用程序中检查内存使用情况的最佳方法是什么?
我的托管服务提供商告诉我要经常回收 IIS 应用程序池以提高网站的速度。这就是“推荐做法”吗?当然我不应该经常重新启动我的应用程序吗?我宁愿找出这是否是我的应用程序中的内存使用问题并纠正它。因此,您使用的任何提示和最佳做法也会很有帮助。
该应用程序基于 ASP.NET MVC3、C# 和 EF Code First。任何指导,链接表示赞赏。
编辑:
我发帖后发现了这个页面,非常有用。但我还是想听听其他意见。
ASP.NET MVC and EF Code First Memory Usage
谢谢
【问题讨论】:
标签:
asp.net-mvc-3
memory-management
ef-code-first
【解决方案1】:
我有一个从不回收的网站(直到机器每周重新启动)
您的应用程序通常应该保持正常运行。如果没有,则有一些泄漏。
这可能是因为
- 缓存永不过期
- 缓存永不过期
- 会话存储不断增长,永不超时
- ObjectContexts 永远不会被释放并保留在会话中,等等
应该处置的对象不是
通过依赖注入容器创建的对象未设置为在每次请求后释放,因此可能具有不断增长的内部集合。
还有更多的原因 - 但这些是一些主要的原因。
所以问题实际上是“没有最佳实践 - 这取决于您的应用”
如果您在重启期间担心当前会话,请记住重启可能很快,并且允许完成当前请求(有时)并且表单身份验证令牌将在重启后继续存在,但会话不会,除非您配置 out进程状态服务器。
如果您的内存使用量持续增长,则设置重启计划,否则每周执行一次或从不执行 - 或者在内存到达 XYZ 后设置然后重置。一旦达到某个阈值,ASP.NET 将根据主机在 memoryLimit 上的设置自动重新启动:
http://msdn.microsoft.com/en-us/library/7w2sway1.aspx
【解决方案2】:
默认情况下,IIS 会每隔一段时间(我认为是 29 小时左右)自动回收应用程序池,但这肯定是由主机设置的,无论进程使用的内存有多少或有多少。回收触发器可以是时间间隔,也可以是进程达到某个内存使用限制时。我确定任何共享主机都设置了它们。
关于内存使用情况,你可以使用 GC.GetTotalMemory 方法,它会给你一个大概的使用情况。即使在使用 Perfmon 时,读数也不是很准确,但它会给你一个想法。
//global.asax.cs
void Application_EndRequest(object o,EventArgs a)
{
var ctype=Context.Response.Headers["Content-Type"];
if (ctype == null || !ctype.Contains("text/html")) return;
Context.Response.Write(string.format("<p>Memory usage: {0}</p>",GC.GetTotalMemory(false)));
}
请注意,在 GC 启动之前,您会看到使用量不断增加,并且使用量将下降到更“现实”的值。
如果你有钱我推荐一个专门的工具,比如Memory profiler
如果应用程序出现内存或性能问题,您可以做的其他事情至少做好准备:
- 应用程序的适当分层意味着您可以重构效率较低的部分而不影响其他部分。
- 存储库模式将非常有帮助,因为您可以开始使用 EF,发现 EF 使用了很多内存(如您找到的链接中所示),但随后您可以切换存储库实现以使用 PetaPoco 或 Dapper .net。
- 一般来说,OR\M 更像是一个重型库,如果应用程序不需要 ORM 功能而只是一种使用数据库的快速方法,那么从一开始就使用上面提到的 mico-Orm。
- 始终处置实现 IDisposable 的对象。
- 处理大型数据库记录时,使用分页。这对服务器资源的使用和用户体验都有好处
- 尽可能地应用 YAGNI(You Aint Gonna Need It)原则,这在某种程度上暗示了一点 TDD :)