我正在开发一个在Windows Server 2016和IIS10.0上运行的网站(虽然我们的生产服务器运行Windows Server 2012 R2和IIS7),并且最近发现每次加载页面时它都会泄漏内存,转到新页面或刷新当前页面。该网站使用ASP经典页面和ASP.NET的混合(因为该网站正在慢慢转变为后者)。
最初我发现很多ASP经典页面没有正确关闭/处理它们的对象(例如ADODB记录集),但在修复后仍然存在泄漏。
然后我创建了两个完全准系统的页面,一个用于aspx,一个用于asp,它们只包含HTML的最低要求(以及语言的各种必需品,例如aspx页面中的CodeFile行)。不断刷新这两个页面继续产生泄漏,这使我怀疑这是一个IIS配置错误。
我使用DebugDiag尝试获取内存转储但结果似乎没有结果,因为cachfile.dll和sqlncli11.dll似乎泄漏了内存。
然后我交换到windbg,回收了应用程序池,并加载了我们最简单的页面(这是ASP经典中的登录页面)。然后,我附上了windbg,用dump dumpap -stat转储堆并保存它,分离调试器,刷新页面10次,并重复转储过程。在对数据进行排序并对两个转储进行分类之后,看起来HttpContext,HttpRequest,HttpResponse和其他相关类看起来永远存在于内存中而不是释放,因为对象计数增加了与刷新页面大致相同的次数,给予或采取一点,其他地方没有其他明显的增加。我还转储了Session集合,以确定它不会创建多个会话,只有一个会话没有存储变量就能正确显示。
这是我在第一次加载时看到的样本:
SELECT Title FROM table WHERE Status=$variable
10次刷新后我看到了什么:
00007ff9611e12c0 90 5760 System.Web.HttpAsyncResult
00007ff9611e0348 16 6784 System.Web.HttpContext
00007ff9611e08f8 16 6272 System.Web.HttpRequest
所以,我已经做了最后的事情,但没有产生任何区别:完全禁用页面缓存,减少脚本超时,以及更改请求队列超时。这些都没有能够阻止泄漏。
以前有没有人经历过这个?有没有办法解决它或更深入的方法来找出内存泄漏的确切原因?我是否缺少一些控制请求生命周期的IIS设置?
我有下面提到的两个转储,如果有任何帮助的话。我在Notepad ++中对它们进行了区分,以识别计数/大小差异
First Page Load Dump
10 Refreshes Dump