AppDomain 的作用
AppDomain 类似于一个轻量级进程,它是 .net / mono 代码运行时的一个逻辑容器。
一般情况下,我们开发的代码都运行在“运行时”为我们创建的 AppDomain 中(即默认 AppDomain),察觉不到 AppDomain 的存在,也不太需要关注 AppDomain。但在另外一些情况下,有可能需要在应用程序中创建其他 AppDomain,例如:
- 动态卸载程序集:我们知道在 .net / mono 中,可以在运行时动态加载程序集,但却无法将已加载到内存的特定程序集卸载掉,这意味着在程序运行期间无法更新被加载的程序集。而这个功能在某些程序设计中是非常必要的,最常见的就是插件架构。此外,由于已加载的程序集要在应用程序结束时才被释放,这也造成了不必要的内存占用。现在,通过 AppDomain 可以实现此目的。
- 实现程序集隔离:一些容易引起崩溃的代码可以考虑单独运行在一个 AppDomain 中。譬如,Asp.net 中就利用不同的 AppDomain 来防止一个应用程序的崩溃影响其他 Asp.net 应用程序,同时还可以在不重启系统、不重启 IIS、不影响 Asp.net 自身服务的情况下将一个 AppDomain 卸载掉,然后启动新的 AppDomain,理想情况下可以实现 web 系统的长时间在线(这以往是昂贵的 unix 的特性,现在终于被微软“借鉴”了)。
- 限制代码安全权限:在一些情况下,为了防止某些非受信代码可能对其他 AppDomain 造成的潜在有害影响,可以对其应用不同的安全级别,以确保关键资源的安全性。
- 加载相同程序集的不同版本:这个在 COM 时代是一个大问题,现在通过 AppDomain,即可实现在一个进程中同时加载不同版本的两个程序集,且可以做到良好的兼容性。
- 有效利用资源:从性能上考虑,有些程序集可能会消耗大量资源,尽管在托管环境下基本上不存在资源消耗漏洞,但总会存在特定时间密集访问、造成大量资源消耗的情况,这时可以考虑创建单独的 AppDomain,在资源消耗超过临界点后卸载 AppDomain,以适应系统运行要求。
- 减少内存占用:在.net 中允许不同 AppDomain 共享程序集,前提是这些程序集必须具有强名称,且位于 GAC 中。例如,在 Asp.net 中,程序集共享策略默认使用的是 MultiDomainHost,这意味着 GAC 中所有程序集都将作为共享 (domain neutral) 程序集被所有 AppDomain(即所有 Asp.Net 应用程序)共用,我们可以想象得到这可以带来多少内存节约。