1. 托管程序集同時(shí)包含元數(shù)據(jù)和IL。IL是與CPU無關(guān)的機(jī)器語言。可將IL是為一種面向?qū)ο蟮臋C(jī)器語言。
2. IL也是能使用匯編語言來寫的,MicroSoft專門提供了一個(gè)名為ILAsm.exe的IL匯編器和一個(gè)名為ILDasm.exe的IL反匯編。3. 高級(jí)語言只公開了CLR的所有功能的一個(gè)子集,IL匯編語言允許開發(fā)人員訪問CLR的所有功能。如果你需要當(dāng)前使用的語言不支持的CLR功能,可以使用IL語言或者其他CLR語言。4. 為了執(zhí)行一個(gè)方法,首先必須將它的IL轉(zhuǎn)換成為本地CPU指令,這是CLR的JIT(just-in-time或"即時(shí)")編譯器的職責(zé)。5. 展示一個(gè)方法首次調(diào)用發(fā)生的事情。①在Main方法執(zhí)行之前,CLR會(huì)檢測(cè)出Main的代碼引用的所有類型。這會(huì)使CLR分配一個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu),用于管理對(duì)所引用的類型的訪問。圖1-4中,Main方法引用了一個(gè)Console類型(或就叫做Console類),這將讓CLR分配一個(gè)內(nèi)部結(jié)構(gòu)。在這個(gè)結(jié)構(gòu)中,Console類型定義的每個(gè)方法都有一個(gè)相對(duì)應(yīng)的記錄項(xiàng)。每一個(gè)記錄項(xiàng)都容納一個(gè)地址(但目前還是沒有的,還沒到這一步),根據(jù)地址即可找到方法的實(shí)現(xiàn)。②初始化CLR分配了一個(gè)內(nèi)部結(jié)構(gòu),CLR將每個(gè)記錄項(xiàng)都設(shè)置成包含在CLR內(nèi)部的一個(gè)未文檔化的函數(shù)(就理解成未公開的,只有微軟自己清楚的函數(shù))。姑且就將這個(gè)函數(shù)命名為JITCompiler(MSDN找不到這個(gè)函數(shù),為了說明流程,自己取的函數(shù)名,因?yàn)檎嬲暮瘮?shù)名微軟沒公開)③Main方法首次調(diào)用WriteLine時(shí),JITCompiler也就被調(diào)用了。JIT函數(shù)負(fù)責(zé)將一個(gè)方法的IL代碼編譯成本地CPU指令。由于IL是"即時(shí)"編譯的,所有通常將這個(gè)組件成為JIT編譯器或JITter。④JITCompiler函數(shù)被調(diào)用時(shí),它知道要調(diào)用的是哪個(gè)方法,以及具體是什么類定義了該方法。于是乎,JITCompiler會(huì)在定義該類型的程序集的元數(shù)據(jù)中查找被調(diào)用的方法的IL。⑤接著就是驗(yàn)證IL代碼,并將IL編譯成為本地CPU指令。本地CPU指令被保存到了一個(gè)動(dòng)態(tài)分配的內(nèi)存塊中。⑥然后,JITCompiler在CLR為類型創(chuàng)建的內(nèi)部數(shù)據(jù)結(jié)構(gòu),找到與被調(diào)用的方法對(duì)應(yīng)的那一條記錄項(xiàng),修改最初對(duì)JITCompiler的引用,讓它現(xiàn)在指向內(nèi)存塊(其中包括了剛才編譯好的本地CPU指令)的地址。⑦最后,JITCompiler函數(shù)跳轉(zhuǎn)到內(nèi)存塊中的代碼,繼續(xù)執(zhí)行里面的具體的功能代碼,這些代碼執(zhí)行完后,會(huì)返回到Main中,并像往常一樣繼續(xù)執(zhí)行。
⑧現(xiàn)在,Main要執(zhí)行第二個(gè)WriteLine方法了。這一次,由于第一次已對(duì)WriteLine的代碼進(jìn)行了驗(yàn)證和編譯,所以會(huì)直接執(zhí)行內(nèi)存塊中的代碼,完全跳過JITCompiler函數(shù)。第二個(gè)WriteLine方法執(zhí)行完畢,會(huì)再次返回Main。圖1-5展示了第二次調(diào)用WriteLine時(shí)發(fā)生的事。

6. 對(duì)于大多數(shù)應(yīng)用程序,因JIT編譯造成的性能損失并不顯著。大多數(shù)引用程序會(huì)反復(fù)調(diào)用相同的方法。看到上面,你對(duì).NET的“第一次”是否有了顛覆性的認(rèn)識(shí)了。7. CLR的JIT編譯器會(huì)對(duì)本地代碼進(jìn)行優(yōu)化,代碼優(yōu)化后會(huì)獲得更出色的性能。9. IL是基于棧的。這就意味著它的所有執(zhí)行都要將操作數(shù)壓入(push)一個(gè)執(zhí)行棧,并處棧彈出(pop)結(jié)果。10. IL提供的最大優(yōu)勢(shì)在于應(yīng)用程序的健壯性和安全性。將IL編譯成CPU指令時(shí),CLR會(huì)執(zhí)行一個(gè)名為驗(yàn)證(verfication)的過程。這個(gè)過程會(huì)檢查高級(jí)IL代碼,確定代碼所做的一切都是安全的。11. C#編譯器默認(rèn)生成的是安全(safe)代碼,這種代碼是否安全是可驗(yàn)證的。然而,C#編譯器也允許開發(fā)人員寫不安全(unsafe)代碼。12. 不安全代碼允許直接操作內(nèi)存地址,并可操作這些地址處的字節(jié),通常只有在與非托管代碼進(jìn)行互操作,或在提升效率極高的一個(gè)算法的性能時(shí),才會(huì)這么做。13. MicroSoft提供一個(gè)名為PEverify.exe的好、程序,它檢查一個(gè)程序集的所有方法,并報(bào)告其中含有不安全代碼的方法。新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注