標籤:style blog http io os 使用 ar strong 檔案
這本書這幾年零零散散讀過兩三遍了,作為經典書籍,應該重複讀反覆讀,既然我現在開始寫博了,我也準備把以前覺得經典的好書重讀細讀一遍,並且將筆記整理到部落格中,好記性不如爛筆頭,同時也在寫的過程中也可以加深自己理解的深度,當然同時也和技術社區的朋友們共用。
程式集
- 描述:一個或多個類型定義檔案及資源檔的集合
- 特徵:可重用、可保護、可版本控制的單元
- 產生:可通過C#編譯器(或其他編譯器)或AL.exe產生
- 組成:
- 託管模組(module)
- PE頭,PE32或PE32+,面向CPU架構的資訊
- CLR頭,面向CLR的資訊,版本、入口、中繼資料等
- 中繼資料,原始碼類型成員定義和引用的類型成員定義
- IL代碼,編譯器產生的Managed 程式碼,物件導向的機器語言
- 資源檔
- 資訊清單
CPU架構
針對x86、x64和IA64三種平台有三個版本的CLR,資訊包含在PE頭中
- 跨CPU架構:使用anycpu,相容所有CPU架構平台
- 指定CPU架構:與非託管互動時,考慮到非託管介面的平台特定性,才使用特定CPU架構
| /開關 |
託管模組 |
x86 windows |
x64 windows |
IA64 windows |
| anycpu |
PE32/不指定 |
32位 |
64位 |
64位 |
| x86 |
PE32/x86 |
32位 |
Wow64運行 |
Wow64運行 |
| x64 |
PE32+/x64 |
不運行 |
64位 |
不運行 |
| Itanium |
PE32+/Itanium |
不運行 |
不運行 |
64位 |
中繼資料
- 編譯時間支援,已包含和引用的類型/成員有關的全部資訊
- 智能感知(Intelligence),成員(方法、屬性、事件和欄位)及方法參數
- 驗證型別安全
- 反射和序列化(對象啟用與對象重建)
- 記憶體回收,垃圾收集器能判斷物件類型以及對象欄位的引用資訊
執行流程
- 判斷是否存在已編譯的本地代碼,如果存在直接執行(3),否則開啟JIT編譯器
- 啟動JIT編譯(MSCorEE.dll)
- 在中繼資料中尋找調用資訊(方法等)
- 擷取該調用資訊的IL
- 分配記憶體塊DynamicMemory
- 編譯IL為本地CPU指令,並儲存到DynamicMemory
- 修改Type表調用指標指向DynamicMemory
- 跳轉到DynamicMemory中的本地代碼
- 執行本地代碼(CPU指令)
編譯過程
有兩個C#編譯器開關會影響代碼的最佳化:/optimize和/debug,請看下錶:
| 編譯器開關設定 |
C# IL代碼品質 |
JIT本地代碼品質 |
| /optimize- /debug(預設) |
未最佳化 |
有最佳化 |
| /optimize- /debug(+/full/pdbonly |
未最佳化 |
未最佳化 |
| /optimize+/debug(-/+/full/pdbonly |
有最佳化 |
有最佳化 |
優缺點比較:
- 未最佳化(/optimize-),未最佳化IL代碼,包含許多NOP(no-operation)指令,還包含分支指令,優點是即使調試
- 最佳化的IL代碼,編譯器刪除多餘的NOP和分支指令,代碼更小,但卻難以單步調試
編譯器預設調試配置
- Debug: /optimize- /debug:full
- Release: /optimize+ /debug:pdbonly
效能神器 – JIT
- 將IL編譯為本地代碼時,對環境的理解比其他編譯器更加深刻
- 產生面向特定CPU的指令,有效利用不同平台的資源提高效率
- 最佳化代碼,使IL更加輕量,並且更容易理解
雞肋?NGen.exe
優點:
- 先行編譯儲存在磁碟上,加快啟動速度
- 減小工作集,進程之間共用代碼(通過記憶體映射)
缺點:
- 對代碼無最佳化
- 較差的執行時效能(無特定CPU指令最佳化,運行時欄位無法直接存取)
部署
| |
私人部署 |
全域部署 |
| 弱命名程式集 |
支援 |
不支援 |
| 強命名程式集 |
支援 |
支援 |
私用組件部署特徵:引用程式集存放在基目錄或者基目錄的子目錄
探測範圍:基路徑 - 配置路徑 - 相同名稱子路徑 - 語言文化子目錄
私用組件目錄配置:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="AuxFiles1,AuxFiles2" /> </assemblyBinding> </runtime></configuration>
其他(Other Tips)
SDK工具
- IL編譯及反編譯 – ILAsm.exe/ILDasm.exe
- CLRVer.exe 查看CLR版本
- DumpBin.exe和CorFlags.exe,查看託管模組所嵌入的資訊
- 安全檢查工具:PEVerify.exe
IL是中繼語言,支援混合編程,C#只是利用CLR的一個子集,IL則是完全面向CLR的
CLR啟動入口(MSCorEE.dll)(3種CPU架構3個版本,負責載入程式集)
WoW64能類比x86指令集
CLS語言規範,規範混合語言之間的互操作 [assembly: CLSCompliant(true)]
語言互操作
- Managed 程式碼調用dll中的非託管函數(PInvoke平台叫用)
- Managed 程式碼使用現有的COM組件
- Unmanaged 程式碼使用託管類型
- 開源實現:http://CLRInterop.CodePlex.com
回應檔,rsp檔案,包含一些編譯切換參數,系統全域回應檔自動引用預設程式集
程式集搜尋目錄及順序
- 工作目錄
- CSC.exe本身目錄
- /lib 指定的目錄
- LIB環境變數指定的目錄
多檔案程式集,編譯器將module合并,addmodule開關,也可以使用AL.exe,用處:
- 單獨檔案儲存體類型,允許累加式更新,分批打包/部署
- 嵌入資源
- 不同的語言進行實現,然後再合并
程式集文化
- 語言文化包括特定文化或者文化中性
- 附屬組件,使用System.Resources.ResourceManager訪問附屬組件的資源
- 設定方式 1:AL.exe /culture 2:[assembly:AssemblyCulture(“de-CH”)]
讀書筆記—CLR via C#章節1-2