咱們知道在.net平臺中反射提供了在運行時動態的得到程序或程序集中每個類型(包括類、結構、委託、接口和枚舉等)的成員和成員的信息,從而使得咱們開發人員在運行時可以利用這些信息構造和使用對象。咱們知道反射中能夠經過System.Reflection.Assembly命名空間下的 Assembly.Load 動態的加載程序集信息,獲取咱們想要的一切信息。那麼當咱們動態加載完程序集並對其使用完以後,咱們想卸載掉它,不想在內存中留下垃圾信息,這時咱們發現Assembly並無提供Assembly.UnLoad的方法讓咱們動態的卸載程序集,這是爲何呢?dom
首先咱們之因此要實現 Assembly.Unload 函數,主要是爲了回收空間和更新版本兩類需求。前者在使用完 Assembly 後回收其佔用資源,後者則卸載當前版本載入更新的版本。例如 ASP.NET 中對頁面用到的 Assembly 程序的動態更新就是一個很好的使用示例。但若是提供了 Assembly.Unload 函數會引起下面的一些問題:
1.爲了保證CLR 中代碼所引用的代碼地址都是有效的,必須跟蹤諸如 GC 對象和 COM CCW 之類的特殊應用。不然會出現 Unload 一個 Assembly 後還有 CLR 對象或 COM 組件使用到這個 Assembly 的代碼或數據地址,進而致使訪問異常。而爲了不這種錯誤進行的跟蹤,目前是在 AppDomain 一級進行的,若是要加入 Assembly.Unload 支持,則跟蹤的粒度必須降到 Assembly 一級,這雖然在技術上不是不能實現,但代價太大了。
2.若是支持 Assembly.Unload 則必須跟蹤每一個 Assembly 的代碼使用到的句柄和對現有託管代碼的引用。例如如今 JITer 在編譯方法時,生成代碼都在一個統一的區域,若是要支持卸載 Assembly 則必須對每一個 Assembly 都進行獨立編譯。此外還有一些相似的資源使用問題,若是要分離跟蹤技術上雖然可行,但代價較大,特別是在諸如 WinCE 這類資源有限的系統上問題比較明顯。
3.CLR 中支持跨 AppDomain 的 Assembly 載入優化,也就是 domain neutral 的優化,使得多個 AppDomain 能夠共享一份代碼,加快載入速度。而目前沒法處理卸載 domain neutral 類型代碼。這也致使實現 Assembly.Unload 完整語義的困難性。函數
基於上述的願意目前並不支持動態的卸載程序集信息。優化
想了解更詳細的緣由可參考大神的博客:https://blogs.msdn.microsoft.com/jasonz/2004/05/31/why-isnt-there-an-assembly-unload-method/.net