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 應用程序)共用,我們可以想象得到這可以帶來多少內存節約。