MVC3内存管理

发布于 2025-01-07 22:26:42 字数 431 浏览 1 评论 0原文

检查 ASP.NET MVC3 应用程序中内存使用情况的最佳方法是什么?

我的托管提供商告诉我要经常回收 IIS 应用程序池,以提高网站的速度。这是“推荐的做法”吗?我当然不需要经常重新启动我的应用程序吗?我更愿意找出我的应用程序中是否存在内存使用问题并纠正它。所以任何提示和信息您使用的最佳实践也会很有帮助。

该应用程序基于 ASP.NET MVC3、C# 和 EF Code First。任何指导,链接表示赞赏。

编辑: 我发帖后发现了这个页面,非常有用。但我还是想听听其他的看法。

ASP.NET MVC 和 EF Code First 内存使用情况

谢谢

What is the best way to check memory usage in an ASP.NET MVC3 application?

I have been told by my hosting provider to recyle the IIS application pool every so often to improve the speed of the site. Is this what is 'recommended practice'? Surely I shouldn't need to restart my application every so often? I'd much rather find out if it is an issue with memory usage in my application and correct it. So any tips & best practices you use would be quite helpful too.

The application is based on ASP.NET MVC3, C# and EF Code First. Any guidance, links appreciated.

EDIT:
I found this page after I posted, which is quite useful. But I'd still like to hear any other views.

ASP.NET MVC and EF Code First Memory Usage

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

卸妝后依然美 2025-01-14 22:26:42

我有一个永远不会回收的站点(直到每周重新启动机器)

您的应用程序通常应该保持良好的性能。如果没有,则存在泄漏。
发生这种情况的原因是

  1. 缓存永不过期
  2. 缓存永不过期
  3. 会话存储不断增长并且永不超时
  4. ObjectContext 永远不会被释放并保留在会话中,等等
  5. 应该释放的对象不是

  6. 通过依赖项注入容器创建的对象不会设置为在每次请求后释放,因此可能具有不断增长的内部集合。

还有更多原因 - 但以下是几个主要原因。

所以问题实际上是“没有最佳实践 - 这取决于您的应用程序”

如果您担心重新启动期间的当前会话,请记住重新启动可以很快,并且允许当前请求完成(有时)并形成身份验证令牌将在重新启动后继续存在,但是会话不会,除非您配置进程外状态服务器。

如果您的内存使用量持续增长,则设置一个重新启动计划,否则每周一次或从不执行 - 或者在内存转到 XYZ 后进行设置,然后重置。一旦达到某个阈值,ASP.NET 将自动重新启动,具体取决于托管服务商在内存限制上的设置:
http://msdn.microsoft.com/en-us/library/7w2sway1.aspx

I have a site that never recycles (until the machine is rebooted weekly)

Your application generally should keep performing fine. If it doesn't, there is some leak.
This can occur because

  1. Cache never expires
  2. Cache never expires
  3. Session storage keeps growing and never times out
  4. ObjectContexts are never disposed and kept in the session, etc
  5. Objects that should be disposed aren't

  6. Objects that are created via a dependency injection container aren't setup to release after each request, and thus potentially have internal collections that keep growing.

There are more causes - but these are a few main ones.

So the question really is 'there is no best practice - it depends on your app'

If you are worried about current sessions during a restart, keep in mind a restart can be quick and current requests are allowed to finish (sometimes) and forms authentication tokens will survive the restart, however sessions will not unless you configure an out of process state server.

If your memory usage keeps growing, then setup a restart schedule, otherwise do once a week or never - or setup once memory goes to XYZ then reset. ASP.NET will restart automatically once a certain threshold is reached as well based on what the hoster has setup on memoryLimit:
http://msdn.microsoft.com/en-us/library/7w2sway1.aspx

ペ泪落弦音 2025-01-14 22:26:42

默认情况下,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 启动并且使用量将下降到更“实际”的值。

如果您有钱,我推荐一个专门的工具,例如 内存分析器

您可以在以下位置执行其他操作:如果应用程序存在内存或性能问题,至少要做好准备:

  • 应用程序的正确分层意味着您可以重构效率较低的部分而不影响其他部分。
  • 存储库模式将非常有用,因为您可以开始使用 EF ,发现 EF 使用大量内存(如您找到的链接中所示),然后您可以将存储库实现切换为使用 PetaPoco 或 Dapper.net。
  • 一般来说,OR\M 更像是一个重型库,如果应用程序不需要 ORM 功能而只是一种使用数据库的快速方法,请从一开始就使用像上面提到的那样的 mico-Orm。
  • 始终释放实现 IDisposable 的对象。
  • 处理大型数据库记录时,请使用分页。这对服务器资源使用和用户体验都有好处
  • 尽可能应用YAGNI(你不会需要它)原则,这在某种程度上意味着一点TDD:)

By default IIS recycles the application pool automatically at an interval (I think is 29 hours or so) but that is surely set by the host, no matter how little or how much memory you're the process is using. THe recycling trigger can be a time interval or when the process hits a certain memory usage limit. I'm sure any shared host has both of them set.

About memory usage, you can use the GC.GetTotalMemory method which will give you an approximate usage. Even when using Perfmon the readings aren't very accurate but it gives you an idea.

//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)));
 }

Be aware that you'll see the usage increasing increasing until the GC kicks in and the usage will drop to a more 'realistic' value.

If you have the money I recommend a specialized tool such as the Memory profiler

Other things you can do to at least be ready if the application has memory or performance problems:

  • Proper layering of the application, means you can refactor the more inefficient parts without affecting the others.
  • The Repository pattern will be very helpful, because you can start using EF , find out that EF uses to much memory (like in the link you've found), but then you could switch the repository implementation to use PetaPoco or Dapper.net.
  • In general an OR\M is more of a heavy library, if the application doesn't need ORM features but just a quick way to work with a db, use from the beginning a mico-Orm like those mentioned above.
  • Always dispose objects implementing IDisposable.
  • When dealing with large db records, use pagination. It's good for both server resources usage and user experience
  • Apply the YAGNI (You Aint Gonna Need It) principle as much as possible, this somehow implies a bit of TDD :)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文