我们正在运行一些 X64 Win Server 2012 网络服务器(即 IIS 8)。
我们注意到盒子上的可用内存一直保持在 5-10% 的可用空间。我们实际上在这些机器上运行了很多应用程序(13 个站点,13 个应用程序池中的 80 个应用程序)。每个站点的大部分代码都是重复的,因为它们对应于不同的数据库和物理站点,但应用程序是相同的。
我们非常有信心在应用程序中存在内存泄漏,因为内存一直在增长,所以我们直接研究这个问题,但我感到困惑的是 IIS 的内存分配和管理。我想知道 IIS 8 或 x64 服务器是否有任何不同(我们最近才迁移到 x64)。
所以基本上我们的每个网络服务器都有 6GB 的内存,并且有 5-10% 的可用内存。我们确定泄漏的主要应用程序使用了高达 1.2gb 的内存。下一个大约是 800MB,其余的平均大约是 400-500MB(所有这些值都是私有内存,如任务管理器中所见)正如我所说的代码是重复的,所以如果一个站点中存在泄漏,它将在所有他们,只是不同的物理位置可以打开或关闭一些功能,这解释了巨大的差异。
当我们解决问题时,我们决定只增加内存,这样我们就不会遇到问题。所以昨晚我关闭了每台服务器并将内存翻倍至 12GB。今天早上,这 3 台服务器的已用内存分别为 77%、80% 和 82%。所有进程的内存使用量都增加了 1.5-2 倍。
所以现在我很困惑。真的是内存泄漏吗?还是有某种内存预分配?或者它永远不会释放内存,除非另一个进程请求它,例如 SQL Server 或什么?
如果内存翻倍时突然变得如此巨大,是什么让内存水平保持在 6GB?是否设置了阈值?IIS/ASP 在内存不足之前不会进行垃圾收集吗?
任何答案表示赞赏。
不用担心!你可能只是过度缓存!
IIS 中的默认输出缓存配置同时启用内核模式和用户模式缓存。
内核模式缓存由本地 HTTP 驱动程序(又名 http.sys)管理,速度快如闪电,但只能提供“公共”内容,因为它需要能够在请求到达之前响应缓存命中Web应用程序。
不幸的是,这意味着许多请求类型无法在内核模式下缓存,包括授权会话(例如访问需要身份验证的网站)。
您描述的设置类型听起来像是某种多租户客户端服务,让我相信内核模式缓存是不可能的。
另一方面,用户模式缓存在应用程序级别进行管理,缓存对象存储在服务工作进程的内存集中。总缓存大小由配置元素
maxCacheSize
上调用的属性控制。system.webServer/Caching
默认情况下,该
maxCacheSize
属性设置为0
大致转换为Let IIS allocate as much memory as current permissible。如果你有很多连续的小 (<256kb) 命中,但uri 缓存命中率很低,IIS 肯定会吃掉你提供的所有内存。
maxCacheSize
您可以通过降低值或完全禁用服务器上的输出缓存来轻松测试这是否正确。如果您仍然确信您的应用程序存在内存问题,请启动性能监视器并查看“ASP.NET 应用程序”性能计数器对象。
选择 GC 计数器并查看垃圾收集是如何分散的。
Gen0 集合应该代表几乎所有的处置,而大量的 Gen1 和 Gen2 集合可能表明存在比必要的对象生命周期更长的问题——这是内存管理失败的常见症状