ASP.NET MVC和EF Code First Memory Usage

时间:2011-02-18 18:34:34

标签: asp.net-mvc performance entity-framework

我有一个在ASP.NET MVC 3中构建的应用程序,它使用SQL CE进行存储,使用EF CTP 5进行数据访问。

我已经将此站点部署到共享主机,但发现它不断被回收,因为它达到了他们在(专用)应用程序池上设置的100mb限制。

在发布模式下运行时,该站点使用大约110mb RAM。

我尝试过使用SQL Server Express而不是CE,这没什么区别。

唯一显着的区别是我完全删除了EF(使用假的回购)。这使内存使用量降低了30mb-40mb。一个空白的MVC模板使用大约20mb,所以我认为这不是太糟糕了?

“标准”ASP.NET MVC应用程序是否有任何基准?

最好知道其他EF CTP用户获得的内存利用率以及内存分析工具(最好是免费的)的一些建议。

值得一提的是我如何处理EF ObjectContext的生命周期。我正在使用每个请求的会话并使用StructureMap实例化ObjectContext:

For<IDbContext>().HttpContextScoped().Use(ctx => new MyContext("MyConnStringName"));

非常感谢 本

2 个答案:

答案 0 :(得分:26)

我们确实设法显着减少了内存占用。与之前的100 + mb相比,IIS工作进程现在大约为50mb。

以下是帮助我们的一些事情:

  • 检查基础知识。确保在发布模式下编译并在web.config中将编译调试设置为false。很容易忘记这些事情。
  • 将DEBUG符号用于诊断代码。这方面的一个例子是使用像NHProf这样的工具(是的,我之前已经被这个问题搞定了)。最简单的方法是将这些代码包装在#if DEBUG指令中,以确保它不会编译到应用程序的发行版中。
  • 不要忘记SQL。 ORM使您很容易忽略应用程序与数据库的对话方式。使用SQL Profiler或EFProf / NHProf等工具可以准确地向您显示正在发生的事情。在EF的情况下,你可能会感到有点不适,特别是如果你大量使用延迟加载。一旦你完成了这个,你就可以开始优化了(见下文)。
  • 延迟加载很方便,但不应在MVC视图(IMO)中使用。这是我们高内存使用的根本原因之一。由于延迟加载(SELECT N + 1),我们网站的主页创建了59个单独的查询。在为这个页面创建一个特定的视图模型并急切地加载我们需要的关联之后,我们得到了6个在一半时间内执行的查询。
  • 设计模式可以指导您,而不是规则开发您的应用程序。我倾向于尽可能遵循DDD方法。在这种情况下,我真的不想在我的域模型上公开外键。但是,由于EF不像NH那样处理多对一关联(它会发出另一个查询只是为了获取我们已经在内存中的对象的外键),我最终得到了一个额外的查询(每个对象)显示在我的页面上。在这种情况下,我决定为了提高性能,我可以忍受一点代码味道(包括模型中的FK)。
  • 一个常见的“解决方案”是在性能问题上抛出缓存。在制定缓存策略之前识别真正的问题非常重要。我可以将输出缓存应用到我们的主页(请参阅下面的注释),但这并没有改变我在缓存过期时有59个查询命中数据库的事实。

关于输出缓存的说明: 当ASP.NET MVC首次发布时,我们能够进行甜甜圈缓存,即从特定区域缓存页面APART。事实上,如果您在页面上有用户特定信息,那么输出缓存就会变得毫无用处。例如,我们在站点的导航菜单中有登录状态。仅这一点意味着我不能对页面使用输出缓存,因为它也会缓存登录状态。

最终,如何优化应用程序并没有严格的规则。当我们停止使用ORM构建我们的关联(面向我们网站的公共部分)并将其手动加载到我们的视图模型中时,我们的应用程序性能得到了最大的改进。我们无法使用EF来急切加载它们,因为关联太多(导致UNION查询混乱)。

一个例子是我们的标记机制。可以标记BlogPost和Project等实体。标签和可标记实体具有多对多关系。在我们的例子中,最好检索所有标签并缓存它们。然后,我们创建了一个linq投影来缓存我们的可标记实体的关联键(例如ProjectId / TagId)。在为我们的页面创建viewmodel时,我们可以为每个可标记实体构建标记,而无需访问数据库。同样,这是我们的应用程序特有的,但它在性能和降低内存使用方面取得了巨大的进步。

我们在此过程中使用的一些资源/工具:

虽然我们确实在主机公司(Arvixe)应用程序池限制下进行了改进,但我确实有责任向正在查看其Windows经销商计划的人提供建议,这些限制已经到位(从那时起)在宣传计划时,Arvixe在任何地方都没有提到这一点。所以,当某些东西看起来好得不真实(无限制的x,y,z)时,它通常就是。

答案 1 :(得分:0)

有趣的是,我认为他们从这个网址得到了他们的估计:

http://blog.whitesites.com/w3wp-exe-using-too-much-memory-and-resources__633900106668026886_blog.htm

P.S。这是一篇很棒的文章,可以查看你是否正在做任何人所描述的事情。 (例如缓存页面)

P.S.S。刚检查了我们的系统,目前它的运行速度为50兆。我们正在使用MVC 2和EF CTP 4。