日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.Net运行时的相互关系

發(fā)布時間:2025/7/14 asp.net 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .Net运行时的相互关系 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

閱讀目錄

  • 前言
  • 線程堆棧的分配
  • 托管堆上對象的分配
  • 結(jié)束語

?

前言

   .Net中的運行時,以及各個類型、對象、線程堆棧以及托管堆之間的關(guān)系,在初學(xué)者(俺是初學(xué)者中的菜鳥 J)看來,有很多是難以理解的東西,俺在看了CLR Via C# 的前幾章后,現(xiàn)在將文中的大概意思并加以自己的理解,重現(xiàn)運行時,以及各個關(guān)系。希望各位盡量拍磚,多多指出不正確的地方,共同進步。

?線程堆棧的分配

?

???????? 圖1中展示了CLR加載的一個Microsoft Windows進程。在一個進程中,可能會存在多個線程。在創(chuàng)建一個線程時,這個線程會分配到一個1MB大小的堆棧。這個堆棧空間的作用:用于向方法傳遞 實參,并用于存儲在方法內(nèi)部定義的局部變量。圖1展示了一個線程的堆棧(右側(cè))。堆棧都是從高位內(nèi)存向地位內(nèi)存地址構(gòu)建。在左側(cè)圖中,該線程執(zhí)行了一些代 碼,它的堆棧上已經(jīng)有一些數(shù)據(jù)(右圖上半部分灰色區(qū)域)。現(xiàn)在假定線程要執(zhí)行M1方法。?

???????? 在一個方法中,應(yīng)該包含一些開場白代碼,負責在方法開始前對變量進行初始化操作,以及一些收場白代碼,負責方法執(zhí)行完畢之后進行清理工作,以便返回調(diào)用者。當M1方法開始執(zhí)行時,它的開場白代碼在線程的對戰(zhàn)中為局部變量name分配內(nèi)存,如圖2所示:?

接 著,M1中的代碼執(zhí)行,調(diào)用M2方法,將局部變量name作為一個實參來傳遞。這造成name局部變量中的地址被壓入堆棧。在M2方法內(nèi)部,將使用名為s 的形參變量來標識堆棧位置(注意,有的架構(gòu)通過寄存器來傳遞實參以提升性能,但這對于當前的討論來說并不重要)。另外,在調(diào)用一個方法時,還會將一個“返 回地址”壓入堆棧。以便被調(diào)用的方法在完成之后,應(yīng)該返回到這個位置。參見圖3:?

???????? M2方法開始執(zhí)行時,他的開場白代碼在線程的堆棧中為局部變量length 和tally分配內(nèi)存,如圖4。然后,開始執(zhí)行M2方法內(nèi)部的代碼。最終,M2會執(zhí)行到return語句,這時CPU執(zhí)行指針會被設(shè)置成堆棧中剛才存儲的[返回地址] ,而 且M2的堆棧幀會進行輾轉(zhuǎn)開解(unwind)(個人大概理解意思是:釋放M2的內(nèi)部局部變量),然后堆棧內(nèi)部會恢復(fù)到圖2狀態(tài),之后,M1將繼續(xù)執(zhí)行后 面代碼,最終M1也會返回到它的調(diào)用者,這個過程其實跟M2是一樣的,M1執(zhí)行完成之后,M1的堆棧幀會進行輾轉(zhuǎn)開解,恢復(fù)成圖1所示那樣。跟著會執(zhí)行 M1后續(xù)的代碼。圖4:?

托管堆上對象的分配

???????? 討論完了堆棧上的內(nèi)存分配之后,我們再來看下托管堆上對象的分配。我們知道在.Net中值類型是存儲在堆棧上,引用類型是存儲在托管堆上,上面線程堆棧的分配中,name是string類型,屬于引用類型,string的分配屬于比較特殊的部分,這里我推薦:

Artech的大作:字符串的駐留(String Interning)

Anytao的大作:[你必須知道的.Net]第九回:品味類型—值類型與引用類型(中)—規(guī)則無邊

說明:在濤哥的這篇文章中,建議多看看精彩的評論。

???????? 現(xiàn)在,假定有以下兩個類定義如下:

// Employee 類定義
internal class Employee{

public int GetYearEmployed(){…}

public virtual String GetProgressReport(){…}

public static Employee Lookup(String name)(){…}

}

// Manager類定義 繼承自 Employee
internal sealed class Manager:Employee{

public override String GetProgressReport(){…}

}

?? ? ? ? 現(xiàn)在Windows進程已經(jīng)啟動,CLR已經(jīng)加載完成,托管對已初始化,而且已經(jīng)創(chuàng)建好了一個線程連同他的1MB的堆棧控件。該線程已經(jīng)執(zhí)行了一些代碼, 現(xiàn)在馬上就要調(diào)用M3代碼。圖5展示了當前的狀況。M3方法包含的代碼演示了CLR是如何工作的。我們平時不會寫這樣的代碼,因為它們實際上并不做任何有 用的事情。圖5:?

???????? 當JIT編譯器將M3的IL代碼轉(zhuǎn)換成本地CPU指令時,會注意到M3內(nèi)部引用的所有類型:Employee,Int32,Manager 以及String(因為有“Joe”) 。這時,CLR要確保定義了這些類型的所有程序集已經(jīng)加載到AppDomain中。然后,利用程序集的元數(shù)據(jù),CLR提取有關(guān)這些類型的信息,并創(chuàng)建一些 數(shù)據(jù)結(jié)構(gòu)來表示類型本身。圖6展示了用于Employee 和Manager類型對象的數(shù)據(jù)結(jié)構(gòu)。由于線程之前已經(jīng)執(zhí)行了一些代碼,所以不妨假設(shè)int和String的類型對象已經(jīng)創(chuàng)建好了,所以圖中沒有顯示它 們。圖6:?

現(xiàn)在我們來討論下這些類型對象。在創(chuàng)建對象的時候,所有對象除了包含實例成員外,都會再包含兩個額外的成員:類型對象指針同步塊索引。 從上圖中可以看出,Employee和Manager類型對象都有這兩個成員。定義一個類型時,可以在類型的內(nèi)部定義靜態(tài)數(shù)據(jù)字段。為這些靜態(tài)數(shù)據(jù)字段提 供支援的字節(jié)是在類型對象自身中分配的。在每個類型對象中,最后都包含一個方法表。在方法表中,類型中定義的每個方法都有一個對應(yīng)的紀錄項。

Employee 定義了三個方法,所以在它的方法表中有三個紀錄項。同理,Manager只定義了一個方法,所以在Manager的方法表中只有一個紀錄項。

???????? 現(xiàn)在,當CLR確定方法需要的所有類型對象都已創(chuàng)建,而且M3的代碼已經(jīng)編譯后,就允許線程開始執(zhí)行M3的本地代碼。M3的開場白代碼執(zhí)行時,必須從線程 的堆棧中為局部變量分配內(nèi)存(引用類型存儲引用,引用指向?qū)ο笏谕泄芏训钠频刂?#xff0c;此時尚未在托管堆創(chuàng)建對象,所以會賦值為null,在用new新增對 象后,才會指向新對象的引用地址,值類型存儲變量本身,),在圖中代碼中,CLR會自動將所有局部變量初始化為null或0。圖7:?

???????? 然后M3繼續(xù)執(zhí)行代碼,緊接著構(gòu)造一個Manager對象,這個構(gòu)造操作會在托管堆中創(chuàng)建Manager類型的一個實例,可以看出,和所有對象一 樣,Manager對象也有一個類型對象指針和同步塊索引。該對象還包含容納Manager類型定義的所有實例數(shù)據(jù)字段及其任何基類定義的所有實例字段所 需的字節(jié)。任何時候在堆上新建一個對象,CLR都會自動初始化內(nèi)部類型對象指針成員,讓它引用與對象對應(yīng)的類型對象(本例就是Manager類型對象)。 此外,CLR還會首先初始化同步塊索引,并將對象的所有實例字段設(shè)為null或0,然后才會調(diào)用類型構(gòu)造器(可能會修改某些實力字段),隨后 new操作符會返回新建的Manager對象的內(nèi)存地址,該地址保存在變量e中(e在線程的堆棧上)。圖8:?

緊 接著M3的下一行代碼調(diào)用Employee的靜態(tài)方法Lookup。在調(diào)用一個靜態(tài)方法時,CLR會定位與定義靜態(tài)方法的類型對應(yīng)的類型對象。然 后,CLR在類型對象的方法表中定位引用了被調(diào)用方法的紀錄項,然后對方法進行JIT編譯(如果需要的話),最后調(diào)用JIT編譯過的代碼。就本例來說,我 們假定Employee的Lookup方法要查詢一個數(shù)據(jù)庫來查找Joe。這里Lookup是返回一個Employee類型的對象。假定數(shù)據(jù)庫指出Joe 是公司的一名經(jīng)理,所以在內(nèi)部,Lookup方法在堆上構(gòu)造一個新的Manager對象,初始化它,然后返回該對象的地址,這個地址保存到局部變量e中。 操作的結(jié)果如圖9所示:?

???????? 注意,此時,e不再引用創(chuàng)建的第一個Manager對象。事實上,由于沒有變量引用這個對象,所以它是將來進行垃圾收集時的主要候選對象。

???????? M3的下一行代碼調(diào)用Employee的非虛實例方法GetYearEmployed。在調(diào)用一個非虛實例方法時,CLR會找到與發(fā)出調(diào)用的變量的的類型 對應(yīng)的類型對象。在本例中,e被定義成一個Employee(假如Employee類型沒有定義這個方法,則會回溯類層次結(jié)構(gòu),在基類查找)。然 后,CLR在類型對象的方法表中找到引用了被調(diào)用方法的紀錄項,對方法進行JIT編譯,然后調(diào)用JIT編譯過的代碼,就本例來說,假定該方法返回5,這個 整數(shù)保存在year中。結(jié)果如圖10:?

???????? M3的下一行代碼調(diào)用Employee的虛實例方法GetProgressReport。在調(diào)用一個虛實例方法時,CLR要做一些額外的工作。首先,它在 發(fā)出調(diào)用的變量中查找,然后跟隨地址到發(fā)出調(diào)用的對象。在本例中,變量e指向Joe 的Manager對象。然后,CLR會檢查對象的內(nèi)部類型對象指針成員,這個成員引用了對象的實際類型。然后,CLR在類型對象的方法表中定位引用了被調(diào) 用方法的紀錄項,對方法進行JIT編譯,然后調(diào)用編譯后的代碼,就本例來說,會調(diào)用Manager的GetProgressReport實現(xiàn),因為e引用 的是一個Manager對象,操作結(jié)果如圖11:?

???????? 注意,如果Employee的Lookup方法發(fā)現(xiàn)Joe只是一個Employee,而不是一個Manager,Lookup會在內(nèi)部構(gòu)造一個 Employee對象,它的類型對象指針將引用Employee類型對象。這樣一類,最終執(zhí)行的就是Emplouee的 GetProgressReport實現(xiàn),而不是Manager的GetProgressReport實現(xiàn)。

???????? 至此,已經(jīng)討論了源代碼、IL和JIT編譯的代碼之間的關(guān)系,還討論了線程的對戰(zhàn)、參數(shù)、局部變量、以及如何引用托管堆上的對象。我們還知道對象中包含一個指針,它指向?qū)ο蟮念愋蛯ο?#xff08;類型對象中包含靜態(tài)字段、方法表、類型對象指針和同步塊索引)。還討論了CLR如何調(diào)用靜態(tài)方法、非虛方法以及虛實例方法。理解這些后,可以深刻認識到CLR的工作方式。這些知識會帶來很大的幫助。

???????? 接下來再更深層一點,看看CLR內(nèi)部發(fā)生的事情。從前面幾個圖中,我們可以看到Employee和Manager創(chuàng)建類型對象時,必須初始化這些成員。那 么,具體初始化什么呢?CLR開始在一個進程中運行時,它會立即為System.Type類型創(chuàng)建一個特殊的類型對象。Employee和Manager 類型對象是該類型的實例。因此,他們的類型對象指針會初始化成Type類型對象的引用。如圖12:?

???????? 當然,System.Type類型對象本身也是一個對象,所以內(nèi)部也同樣包含一個類型對象指針成員。那么這個指針指向誰呢?它指向它本身。因為System.Type類型對象本身是一個類型對象的實例。?

結(jié)束語

???????? 現(xiàn)在,我們總算理解了CLR的整個類型對象及其工作方式,System.Object的GetType方法返回的是存儲在指定對象的“類型對象指針”,這樣,就可以判斷系統(tǒng)中任何對象(包括類型對象)的真實類型。

轉(zhuǎn)載于:https://www.cnblogs.com/zzunstu/p/3408949.html

總結(jié)

以上是生活随笔為你收集整理的.Net运行时的相互关系的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产成人精品777777 | 亚洲视频日韩 | 久久h| 精品电影在线观看 | 欧美日韩国产精品 | 69视频免费 | 国产精品伦一区二区三级古装电影 | 欧美一区二区在线观看视频 | 上海贵妇尝试黑人洋吊 | av日韩精品| 国产一级片免费视频 | 中文字幕精品在线观看 | 国产午夜在线一区二区三区 | 国产无精乱码一区二区三区 | av网址在线免费观看 | 日本男人的天堂 | www.亚洲一区 | 人人澡人人澡人人澡 | 欧美久久久久久久 | 国产精品久久久av | 一级毛片黄色 | 麻豆一区二区99久久久久 | yjizz视频网 国产乱人对白 | 亚洲AV成人无码网站天堂久久 | 精品久久中文字幕 | 怡春院在线视频 | 欧美成人免费一级 | 亚洲一区免费观看 | 久久精品国产成人av | 成人动漫视频在线观看 | 亚洲三级色 | 中文字幕在线有码 | 久久少妇网 | 97爱视频 | 91玉足脚交白嫩脚丫 | 久久尤物视频 | 内射国产内射夫妻免费频道 | 精品综合网 | 日韩女优在线播放 | 免费观看全黄做爰的视频 | 国产一区在线观看视频 | 亚洲日日夜夜 | 精品小视频 | 亚洲jizzjizz| 裸体喂奶一级裸片 | 韩国一二三区 | 亚洲视屏一区 | 国产视频手机在线播放 | 国产吞精囗交久久久 | 最新的黄色网址 | 欧美黄色大片在线观看 | 欧美在线网 | 强辱丰满人妻hd中文字幕 | 国产精品毛片一区二区 | 亚洲成人www| 亚洲国产97在线精品一区 | 一区二区三区四区免费 | 免费福利视频在线观看 | 日本黄网站 | 蜜臀久久99精品久久一区二区 | 天天搞夜夜爽 | 一区二区韩国 | 制服丝袜在线视频 | 亚洲在线不卡 | 成人免费无码大片a毛片抽搐色欲 | 91亚洲精品国偷拍自产在线观看 | 亚洲av乱码一区二区 | 在线免费看av | 啦啦啦av | 97视频免费在线观看 | 99热超碰在线| 欧美精品极品 | 精品亚洲永久免费 | 欧美视频日韩 | 第四色影音先锋 | 日本黄色a级片 | 久久免费公开视频 | 911精品| 少妇人妻互换不带套 | 日本三级播放 | 国产精品久久久久久久久久久久午夜片 | 韩国一区二区在线播放 | www.xxxxx日本 | 青草91 | 涩涩97| 国产中文在线 | 免费观看毛片视频 | 九草av | 91欧美大片 | 美腿丝袜亚洲综合 | 无人码人妻一区二区三区免费 | 日本视频网| 狠狠综合一区 | 国产对白羞辱绿帽vk | 另类二区| 精品黑人一区二区三区 | av网站亚洲| 精品777| 九色91丨porny丨丝袜 |