?
原文標題:
原文地址:https://www.cnblogs.com/1996V/p/9037603.html
共享程序集GAC
我上面說了這么多有關CLR加載程序集的細節和規則,事實上,類似于mscorlib.dll、System.dll這樣的FCL類庫被引用的如此頻繁,它已經是我們.NET編程中必不可少的一部分,幾盡每個項目都會引用,為了不再每次使用的時候都復制一份,所以計算機上有一個位置專門存儲這些我們都會用到的程序集,叫做全局程序集緩存(Global Assembly Cache,GAC),這個位置一般位于C:\Windows\Microsoft.NET\assembly和3.5之前版本的C:\Windows\assembly。
既然是共享存放的位置,那不可避免的會遇到文件名重復的情況,那么為了杜絕該類情況,規定在GAC中只能存在強名稱程序集,每當CLR要加載強名稱程序集時,會先通過標識去GAC中查找,而考慮到程序集文件名稱一致但版本文化等復雜的情況,所以GAC有自己的一套目錄結構。我們如果想將自己的程序集放入GAC中,那么就必須先簽名,然后通過如gacutil.exe工具(其存在于命令行工具中?https://docs.microsoft.com/zh-cn/dotnet/framework/tools/developer-command-prompt-for-vs中)來注冊至GAC中,值得一提的是在將強名稱程序集安裝在GAC中,會效驗簽名。
GAC工具:?https://docs.microsoft.com/en-us/dotnet/framework/tools/gacutil-exe-gac-tool
?
延伸
CLR是按需加載程序集的,沒有執行代碼也就沒有調用相應的指令,沒有相應的指令,CLR也不會對其進行相應的操作。 當我們執行Environment.CurrentDirectory這段代碼的時候,CLR首先要獲取Environment類型信息,通過自身元數據得知其存在mscorlib.dll程序集中,所以CLR要加載該程序集,而mscorlib.dll又由于其地位特殊,早在CLR初始化的時候就已經被類型加載器自動加載至內存中,所以這行代碼可以直接在內存中讀取到類型的方法信息。
在這個章節,我雖然描述了CLR搜索程序集的規則,但事實上,加載程序集讀取類型信息遠遠沒有這么簡單,這涉及到了屬于.NET Framework獨有的"應用程序域"概念和內存信息的查找。
簡單延伸兩個問題,mscorlib.dll被加載在哪里?內存堆中又是什么樣的一個情況?
?