ASP.NET Web应用程序在部署后不会卸载AppDomain

时间:2014-08-29 14:16:33

标签: c# asp.net iis appdomain

当我们部署我们的Web应用程序时,我们将所有代码复制到一个新目录,然后将iis指向该新目录。当我们这样做时,appdomains的数量会增加但不会减少。此外,我们的Application_End事件似乎永远不会发生。

在一些未知的时间内,虽然perfmon仍然报告了两组AppDomain,但系统执行效果非常差,而GC峰值的%时间达到100%。最后,我会回收应用程序池,让应用程序再次顺利运行。

额外信息:在我的开发机器上列出appdomains显示2,但在实时服务器上运行4个...我们只在池中运行一个应用程序,这意味着我们有一些库使用正在创建应用域。

我应该怎么做才能调试发生了什么?什么会阻止app域的卸载?

2014年9月3日更新

在获得更详细的日志信息之后,看起来问题不在于旧的应用程序域,它是在重新启动期间创建的新应用程序域。它不是启动一个新实例的应用程序,而是启动两个实例。有时我们会从旧实例中获取application_end,有时我们不会。

2014年9月4日更新

这两件事情都在发生。使用进程资源管理器,我可以在其中一台计算机上看到旧的应用程序域仍在那里并且已经启动了新的应用程序域。在另一台机器上只有2个应用程序域,但它们的顺序ID存在差距。所以开始了两个实例(我们也从应用程序启动时收到一条日志消息),其中一个实例几乎立即就消失了,留下了2个应用程序域。

2 个答案:

答案 0 :(得分:2)

您可以检查一件事,以帮助解决问题:

Process Explorer实际上有一个.NET Assemblies标签,其中列出了进程加载的所有AppDomain。注意:该选项卡仅对使用.NET Framework的进程显示。

答案 1 :(得分:2)

虽然我不确定这是应用程序没有卸载appdomains的唯一原因,但这肯定是一个原因。实际的答案远没有我用来解决它的步骤那么有趣。

  1. 我写了一个小小的ruby脚本,只针对我们的应用程序在10个线程中发出100个请求(设置jmeter会花费更多时间)。
  2. 运行脚本并在运行时多次更改应用配置文件。这花了几分钟。
  3. 我使用了进程资源管理器来确认确实有4个应用程序域仍然加载到进程中。
  4. 我运行了procdump并创建了一个转储文件。
  5. 将procdump文件加载到visual studio中并单击“仅使用托管进行调试”(即使我不知道该错误是否在托管代码中)
  6. 调试器停在一行代码上,其中调用Application_End的线程正在等待队列完成处理。通过查看变量的值,我能够告诉队列不再处理项目,但我们要等到队列为空。
  7. 更改了代码并重新开始处理,这次卸载了我对Web配置更改启动的所有应用域。