【问题标题】:ASP.NET application on IIS dropping Static resources from memoryIIS 上的 ASP.NET 应用程序从内存中删除静态资源
【发布时间】:2019-11-15 20:53:35
【问题描述】:

我有一个托管在 IIS (Windows 2012R2/IIS 8.5) 上的 ASP.Net Web 应用程序。应用程序不断地从内存中删除静态资源(即静态类/集合),导致随机请求的速度大幅下降。

这通常发生在 IIS 工作进程内存超过 900Mb 左右(在开发设置中,总内存为 4GB),然后下降到 350Mb 左右。我们的生产设置也是如此(16Gb 内存和应用程序最多消耗 1.9GB,然后降至 800Mb)

设置

  • Windows 2012 R2
  • IIS 8.5
  • 目标框架:4.7.2
  • 平台目标:X64(我将它从Any CPU强制转换为X64以排除 32 位内存限制)。

IIS 设置:

  • .Net CLR 版本:4.0
  • 启用 32 位应用程序:错误
  • 启动模式:始终运行
  • 空闲超时:0
  • 空闲超时操作:挂起
  • 私有内存限制:0

如您所见,我已经排除了几乎所有我能想到的。持续下降有什么原因吗? .Net CLR 不应该将静态类保存在内存中而不是随机删除它们吗?还是我错过了什么?

【问题讨论】:

  • 不断掉线,是不是和池子重启有关?
  • 如果一段时间内没有请求,我认为 IIS 只会关闭你 AppDomain。您是否在此静态字段中存储了大量数据?为什么要在静态字段中存储大量数据?如果是某种缓存,为什么不存储在redis中(例如)?
  • @BugFinder 不,我通过启用池重新启动日志记录确保不是这种情况。同样在这种情况下,内存应该下降到零而不是减半。
  • @Achilles “同样在这种情况下,内存应该下降到零而不是减半” - 前提是你没有泄漏内存
  • @Achilles,正如你所说,你有日志记录 - 你能记录 AppDomain.DomainUnload 事件吗?

标签: asp.net iis asp.net-web-api


【解决方案1】:

你说得对,应用程序池应该记录重启事件 - 但我注意到你没有列出完全禁用重启。

默认情况下,IIS 将其应用程序池配置为每 29 小时(1740 分钟)回收一次,这意味着它不会每天在同一时间重新启动,但它会回收。但是,它应该默认执行“重叠回收”,在关闭旧实例之前启动一个新实例。

如果这是由重启事件引起的,有几个选项可能会有所帮助:

  1. 通过将“常规时间间隔”设置为 0 来禁用回收。
  2. 保持启用状态,但使用Application Initialization 功能正确预热您的应用程序。这是 IIS 8 的一部分,是您可以在 7.5 中安装的模块。

您已经将启动模式设置为Always Running,但使用应用程序初始化模块您还可以declare a page,服务器将在启动期间请求以预热您的应用程序:

<system.webServer>
   <applicationInitialization
      doAppInitAfterRestart="true">
      <add initializationPage="/default.aspx" hostName="myhost"/>
   </applicationInitialization>
</system.webServer>

【讨论】:

  • 谢谢我也禁用了该设置,并且内存刷新发生得太频繁了。我可以在几分钟内触发它,所以也不应该这样。
  • 应用程序池也会因其他原因而回收 - 您是否将任何文件写入应用程序根目录中的磁盘 - 这可能导致 IIS 重新编译项目,如果您不小心就会强制重新启动(我们'已经在日志文件、临时缓存等中看到了这一点——有办法增加这个限制)。最后,在网络花园模式下运行 - 您是否更改了默认 1 的“最大工作进程”?如果是这样,您将在每个线程启动时创建一组新的静态变量。
  • 我们确实将日志文件写入磁盘,但它们会转到完全独立的路径以避免任何干扰。由于缓存同步的原因,我们目前没有在网络花园模式下运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多