2012-02-22 22 views
3

在C#中(或者一般情況下可能在.NET中)單個程序集不能從內存中卸載。 卸載只能在AppDomain級別進行。單個程序集無法在C#中卸載的原因是什麼?

我想知道這種設計背後有什麼原因?其他語言支持此功能(C++我認爲)

+1

舊的Jason Zander文章解釋了一些早期的原因 - 我不確定原因是否已經改變,或者他們是否確定沒有迫切需要解決該問題:http://blogs.msdn.com/ b/jasonz/archive/2004/05/31/145105.aspx – 2012-02-22 07:37:33

回答

4

Here is an MSDN blog post列出一些原因爲什麼不。主要問題是:

首先,您正在應用程序域(duh!)中運行該代碼。這意味着有潛在的呼叫站點和呼叫堆棧,其中有地址,期望繼續工作。你有沒有得到一個訪問衝突,你的EIP指向0x ????????這是一個例子,有人釋放了一個DLL,頁面被內存系統取消映射,然後你試圖分支到它。這通常發生在COM中,當您發生引用計數錯誤並且您進行接口方法調用時。我們承擔不起託管代碼的損失。我們必須保證我們知道您正在執行的所有代碼,並且它是類型安全且可驗證的。這意味着明確跟蹤任何可能使用該代碼的東西,包括GC對象和COM互操作包裝器。此跟蹤現在圍繞應用程序域邊界進行處理。在組裝級別跟蹤它變得非常昂貴。

我將在更高級別的語言總結一下:

基本上,事情會出錯,如果你只是刪除可執行代碼出錯的非託管的水平。您將編譯指向其他編譯代碼的代碼不再存在,因此您的代碼將跳轉到無效的區域,並且可能包含任意數據。

這在託管代碼中是不可接受的,因爲事情是安全的並且有一些保證。其中一個保證是你的代碼不能執行任意部分的內存。

要正確處理這個問題,您必須更密切地跟蹤更多的事情,這將是一個很大的開銷。另一種方法是隻在應用程序邊界跟蹤這些事情,這就是所做的。

+0

謝謝。 dll會被動態地加載和跳動。我會假設當某個dll被釋放時,該場景將與該代碼的「第一次調用」相同。也許我忽略了一些微妙之處。 – 2012-02-22 10:38:10

相關問題