【问题标题】:Asp.net Mvc site running out of memoryAsp.net Mvc 站点内存不足
【发布时间】:2011-07-20 08:19:43
【问题描述】:

我有一个奇怪的场景,网站似乎不时地随机耗尽内存:它工作了数周,然后突然一切都抛出内存不足异常,并且一直如此,直到服务器重新启动。它可能在数周或数天后发生。我们无法识别常规模式。

这里是本网站使用的技术资料列表:

  • 网络框架 3.5
  • 带有 C# 的 Mvc 2.0
  • 专用服务器上的 IIS 6.0(无策略限制等)
  • 3 层架构(ui - bll - dal)
  • 自动映射器 1.1.0.118
  • Elmah 1.1
  • FluentValidation 2.0
  • MvcContrib 2.0.95.0
  • MvcSiteMapProvider 3.0.0.1
  • 城堡2.5.2
  • NHibernate 3.0.0.4
  • FluentNHibernate 1.1.0.0
  • PdfSharp 1.31.1789.0
  • MarkdownSharp

除此之外,该网站还包括(通过 iframe)一些旧的旧式 asp 表单。这些表单与旧版网站(完全在 asp 中)上的表单相同,它们存在一些问题,但旧版网站从未耗尽内存。

我已经检查了常见的东西,就像所有 IDisposable 实现类都在 using 语句中,没有无限循环等。

该网站没有做任何奇怪的事情,它从数据库中提取一些数据,例如新闻,在提交某些表单后即时生成一些 pdf,允许用户订阅新闻通讯。平常的东西。

我真的一无所知,我开发了很多网站,几乎在所有地方都使用过提到的库,但这是我第一次遇到这种问题。

我知道这些信息不足以“发现”问题,但如果有人能想到我可能忽略的事情或任何事情,将非常受欢迎:)

编辑:一个可能很重要的细节。我们有另一个网站在同一台服务器上运行(用旧的 asp 制作),它运行得很好,而另一个则卡住了。所以看起来整个服务器内存并没有耗尽,否则它也不会工作。

【问题讨论】:

  • 如果您查看网站的内存消耗量,它是否会随着时间的推移而增加,或者除了这些奇怪的峰值之外它是否稳定?
  • 这很正常。现在应用程序池为 1gb,重新启动池后我能够访问 elmah,我发现很多内存不足异常。还是一头雾水。
  • 您的网站是否必须能够上传文件?我可能是服务器完全过载,太多用户同时上传文件?
  • 网站上没有文件上传功能。最奇特的是使用 PdfSharp 生成 pdf
  • 是 asp.net 进程膨胀还是其他进程?你在使用 InProc sessionstate 模式吗?你在会话中放置数据吗?会议的时间限制是多少?

标签: c# asp.net-mvc out-of-memory


【解决方案1】:

安装DebugDiag。触发它以在进程超出内存阈值时进行转储(例如在 300Mb 处,然后在之后每 100Mb 处)。

比较转储文件应该可以让您了解是什么突然占用了所有内存

【讨论】:

  • 这将是一个不错的选择,但我无法在服务器上安装任何东西,它是专用主机,而不是住房。
  • 有没有办法在内部运行网站并使用负载测试工具重现行为?
【解决方案2】:

我想看看 Castle 是如何配置和使用的,你是否使用 Castle 来解决你的控制器依赖关系,使用 ControllerBuilder.Current.SetControllerFactory 方法?如果这样做,您还必须记住释放控制器实例。

【讨论】:

  • 我没有使用 Castle 来设置控制器工厂。事实上,现在我正在寻找,它现在根本没有使用。它曾经用于 Windsor - IoC,但现在不再使用。一个死的依赖。
  • 好的,那么您应该看看 Richard 所描述的转储文件。同时寻找你声明静态的地方(例如集合),这是一个很好的泄漏候选者
  • 我会检查代码中的任何静态内容,这是个好建议。我不记得使用静态变量之类的了,但最好是安全而不是抱歉。
【解决方案3】:

如果您在 IIS7/7.5 和高负载上托管多应用程序池,请尝试更改 gc 模式。

aspnet.config

[元素](http://msdn.microsoft.com/en-us/library/ms229357.aspx 元素)

【讨论】:

  • 对不起!但我认为这是 IIS6 上内存使用的可用参数。
  • 无论如何,我认为这不是 GC 问题,原因如下:托管语言的优势在于,如果您以糟糕的方式处理内存,当资源耗尽时,GC 就会出现救援。我尝试了有缺陷的代码,生成了无限循环,这将导致 OOM 异常。但是下一次调用,GC 会通过并清理一切。在这种情况下,应用程序池将保持该状态,直到重新启动。所以我认为这是一些导致泄漏的非托管代码,因为 GC 无法处理非托管代码。听起来是对的还是我过于简单化了?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
  • 2011-06-07
  • 2019-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多