新聞中心
這個.Net Compact Framework CLR設(shè)計這個話題被很多人關(guān)注?,F(xiàn)在我們可以從設(shè)計者的角度,深入了解.Net Compact Framework CLR設(shè)計的內(nèi)部結(jié)構(gòu)。這部分我們要討論JIT編譯器的知識。感謝Steven Pratschner,感謝他給我們帶來了這么好的文章。

創(chuàng)新互聯(lián)公司長期為上千多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為五臺企業(yè)提供專業(yè)的成都網(wǎng)站制作、成都做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè),五臺網(wǎng)站改版等技術(shù)服務(wù)。擁有10年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
設(shè)計JIT編譯器
.Net Compact Framework CLR設(shè)計的***章,以后我們還會為大家提供更多的,希望大家關(guān)注。.Net Compact Framework的JIT編譯器與.Net Framework***的不同在于內(nèi)存使用。在內(nèi)存緊張的情況下,.Net Compact Framework可以釋放Jitted代碼,將內(nèi)存返還給操作系統(tǒng)。正如你所預(yù)料的那樣,如此設(shè)計的原因是因為用于存儲jitted代碼的堆是分配在應(yīng)用程序私有的32MB地址空間上的(更多信息可以參考***部分)。除了私有地址空間非常小之外,考慮到它們從來不被分頁,在內(nèi)存受限設(shè)備上運(yùn)行程序,必要時減少空間壓力的設(shè)計是絕對必要的。
當(dāng)程序被執(zhí)行時,JIT編譯器會在堆上分配內(nèi)存,用來存儲每個方法編譯生成的本地代碼。因為編譯和內(nèi)存分配發(fā)生在每個方法運(yùn)行的時候,每次內(nèi)存分配都會讓堆相應(yīng)減少。換句話說,就是JIT堆在小幅度地逐漸增長。在程序運(yùn)行過程中,JIT堆會增長到很大的程度。在Compact Framework的早期版本中,JIT堆的尺寸被限制在一個固定的大小中。在第二版中,這個限制已經(jīng)被去掉了,因此在新方法需要被編譯時,堆會增加。
三種情況的發(fā)生,會導(dǎo)致JIT堆的大部分空間被釋放并將內(nèi)存歸還給OS(這里只所以說“大部分空間”是因為Compact Framework必須始終保留當(dāng)前執(zhí)行應(yīng)用程序方法的jitted代碼)。首先,如果CLR試圖分配更多內(nèi)存時,收到一個來自操作系統(tǒng)的錯誤,JIT堆將會收縮。CLR會認(rèn)為這個失敗表明可用內(nèi)存數(shù)量不足,于是盡可能多的揮手JIT堆中的代碼。從JIT堆中釋放本地代碼的動作是根據(jù)代碼存在期限決定的。其次,當(dāng)一個程序被切換到后臺時,代碼會被回收。在Windows Mobile中,應(yīng)用程序通常不會被關(guān)閉,但是會被切換到后臺。當(dāng)一個程序被切換到后臺時,通過釋放代碼,CLR可以獲得更多可用內(nèi)存供前臺程序使用,這樣可以增加同時運(yùn)行在設(shè)備上應(yīng)用程序的數(shù)量。***,當(dāng)一個托管應(yīng)用程序收到來自Windows CE的WM_HIBERNATE消息時,CLR會回收jitted代碼。當(dāng)OS發(fā)現(xiàn)運(yùn)行的系統(tǒng)資源過低時,會發(fā)出WM_HIBERNATE消息。當(dāng)設(shè)備資源缺乏時,響應(yīng)WM_HIBERNATE消息的代碼回收是CLR釋放內(nèi)存和其他資源操作的一部分。
我在稍后章節(jié)討論自動內(nèi)存管理時,你將會看到,代碼回收是整個垃圾收集的一部分。
Figure 1The size of the JIT heap over the lifetime of an application.
圖1中的一些情況是十分值得注意的。首先,圖中的兩個低點(diǎn)發(fā)生的時間,對應(yīng)于程序被切換到后臺和堆的尺寸太大而開始代碼回收的時間。同樣,注意程序啟動的時候比程序從后臺切換回來時,會有更多代碼被jitted。這大概是因為應(yīng)用程序包含一些初始化代碼,而這些代碼只是在程序開始時被調(diào)用。
因為CLR會在內(nèi)存緊張或者程序切換到后臺時丟棄本地代碼,所以在程序繼續(xù)運(yùn)行時,相同的IL代碼會被再次JIT編譯。正因為如此我們才作出了第二個關(guān)于JIT編譯器的設(shè)計決定:編譯IL代碼的時間通常優(yōu)先于生成本地代碼的質(zhì)量。作為一個優(yōu)秀的編譯器,Compact Framework JIT編譯器做了一些基本的優(yōu)化,但是為了讓應(yīng)用程序保持響應(yīng),就需要更快地生成代碼,更多地優(yōu)化措施要根據(jù)其速度來決定是否執(zhí)行。
JIT編譯器***一個關(guān)鍵設(shè)計原則是不涉及內(nèi)存使用,這樣做是為了讓JIT編譯器更方便移植。我在***部分曾提到,Compact Framework的運(yùn)行環(huán)境不僅要求它能夠在內(nèi)存受限設(shè)備上運(yùn)行,而且需要它可以在不同的處理器上運(yùn)行。.Net Compact Framework目前可以運(yùn)行在包括x86、Arm、SH和MIPS等處理器上,而且還可以根據(jù)要求支持更多的處理器。因為需要跨越不同領(lǐng)域的設(shè)備,JIT編譯器被設(shè)計成花費(fèi)最少時間,便可以支持一種新的處理器類型的架構(gòu)。一種技術(shù)被用來增加可移植性,就是將處理器相關(guān)的操作限制在最小程度。
Why no Native Images?
桌面版的.Net Framework使用一種叫“本地映像”的技術(shù),當(dāng)應(yīng)用程序加載時,IL代碼都需要被JIT編譯器編譯。如果利用了本地映像技術(shù),應(yīng)用程序可以更快地啟動。本地映像是一個保存在硬盤上的文件,包含被編譯好的IL代碼。當(dāng).Net Framework安裝時,它會調(diào)用JIT編譯器生成mscorlib、System.Windows.Forms等類庫的本地CPU指令。當(dāng)應(yīng)用程序啟動時,就可以直接調(diào)用儲存在本地映像中的已經(jīng)生成的本地代碼,從而節(jié)省了JIT編譯這些程序集的時間。用戶也可以為自己編寫的程序集產(chǎn)生本地映像(可以參考.Net Framework SDK中ngen.exe工具的文檔)。
.Net Compact Framework沒有使用本地映像的主要原因是他們的尺寸。根據(jù)本地指令集的不同,一個程序集被JIT編譯后產(chǎn)生的本地代碼大小大約是IL代碼的三到四倍。在壓縮之后,.Net Compact Framework類庫大約是4.5MB。如果相應(yīng)的本地映像是這個尺寸的四倍的話,你就會看到本地映像需要的存儲空間是設(shè)備中可用內(nèi)存中相當(dāng)大的一部分。另外一種可能就是可以將本地映像保存在外部存儲卡上。可是從存儲卡讀取本地映像文件的速度是非常慢的,因此我們不確定啟動時間可以通過本地映像的方法可以縮短。
以上介紹.Net Compact Framework CLR設(shè)計,Compact Framework JIT團(tuán)隊會在每個主要版本中考慮本地映像,也許在CLR的未來某個版本中,我們會看到本地映像,或者類似的技術(shù)。
文章名稱:.NetCompactFrameworkCLR設(shè)計系列之JIT編譯器講解
網(wǎng)站地址:http://www.dlmjj.cn/article/dphchse.html


咨詢
建站咨詢
