溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何分析.Net Compact Framework CLR中的JIT編譯器

發(fā)布時間:2021-11-25 09:21:41 來源:億速云 閱讀:104 作者:柒染 欄目:編程語言

如何分析.Net Compact Framework CLR中的JIT編譯器,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

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

設(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è)備上運行程序,必要時減少空間壓力的設(shè)計是絕對必要的。

當(dāng)程序被執(zhí)行時,JIT編譯器會在堆上分配內(nèi)存,用來存儲每個方法編譯生成的本地代碼。因為編譯和內(nèi)存分配發(fā)生在每個方法運行的時候,每次內(nèi)存分配都會讓堆相應(yīng)減少。換句話說,就是JIT堆在小幅度地逐漸增長。在程序運行過程中,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)存供前臺程序使用,這樣可以增加同時運行在設(shè)備上應(yīng)用程序的數(shù)量。***,當(dāng)一個托管應(yīng)用程序收到來自Windows CE的WM_HIBERNATE消息時,CLR會回收jitted代碼。當(dāng)OS發(fā)現(xiàn)運行的系統(tǒng)資源過低時,會發(fā)出WM_HIBERNATE消息。當(dāng)設(shè)備資源缺乏時,響應(yīng)WM_HIBERNATE消息的代碼回收是CLR釋放內(nèi)存和其他資源操作的一部分。

我在稍后章節(jié)討論自動內(nèi)存管理時,你將會看到,代碼回收是整個垃圾收集的一部分。

如何分析.Net Compact Framework CLR中的JIT編譯器

Figure 1The size of the JIT heap over the lifetime of an application.

圖1中的一些情況是十分值得注意的。首先,圖中的兩個低點發(fā)生的時間,對應(yīng)于程序被切換到后臺和堆的尺寸太大而開始代碼回收的時間。同樣,注意程序啟動的時候比程序從后臺切換回來時,會有更多代碼被jitted。這大概是因為應(yīng)用程序包含一些初始化代碼,而這些代碼只是在程序開始時被調(diào)用。

因為CLR會在內(nèi)存緊張或者程序切換到后臺時丟棄本地代碼,所以在程序繼續(xù)運行時,相同的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的運行環(huán)境不僅要求它能夠在內(nèi)存受限設(shè)備上運行,而且需要它可以在不同的處理器上運行。.Net Compact Framework目前可以運行在包括x86、Arm、SH和MIPS等處理器上,而且還可以根據(jù)要求支持更多的處理器。因為需要跨越不同領(lǐng)域的設(shè)備,JIT編譯器被設(shè)計成花費最少時間,便可以支持一種新的處理器類型的架構(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)大的一部分。另外一種可能就是可以將本地映像保存在外部存儲卡上??墒菑拇鎯ㄗx取本地映像文件的速度是非常慢的,因此我們不確定啟動時間可以通過本地映像的方法可以縮短。

看完上述內(nèi)容,你們掌握如何分析.Net Compact Framework CLR中的JIT編譯器的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI