.Net CLR運(yùn)行時(shí)的相互關(guān)系

昨天同事在部門分享中談到了Android的虛擬機(jī)機(jī)制。正好想到我在學(xué)習(xí).Net CLR的時(shí)候研究過CLR運(yùn)行時(shí)的相互關(guān)系,所以拿出來分享一下。

我們在本文中要搞清楚類型调鲸,對象,線程棧挽荡,托管堆的關(guān)系藐石。

首先你需要對內(nèi)存管理、.net框架和.net clr有個(gè)基本的了解定拟。.net框架

線程棧

我們先來看看一個(gè)加載了CLR的Microsoft Windows的進(jìn)程于微。一個(gè)進(jìn)程可能會(huì)有多個(gè)線程。一個(gè)線程創(chuàng)建時(shí)青自,會(huì)分配到1MB大小的棧角雷。
作用

  • 保存向方法傳遞的實(shí)參
  • 保存方法內(nèi)部定義的局部變量

棧是高位向低位地址構(gòu)建的

一個(gè)線程的棧,準(zhǔn)備調(diào)用M1方法

image.png

分配局部變量name的內(nèi)存

image.png

M1調(diào)用M2方法性穿,把實(shí)參s壓入棧,調(diào)用方法時(shí)雷滚,還需要將“返回地址”壓入棧需曾,被調(diào)用方法結(jié)束后,返回這個(gè)位置祈远。

image.png

M2開始執(zhí)行呆万,最終到達(dá)return語句,指令指針被設(shè)置為棧中的返回地址车份,M2的棧幀(指當(dāng)前線程中調(diào)用棧的一個(gè)方法調(diào)用谋减,每個(gè)方法調(diào)用都會(huì)在調(diào)用棧中創(chuàng)建并壓入一個(gè)棧幀)會(huì)被釋放。線程棧如下圖

image.png

線程將繼續(xù)執(zhí)行M1在調(diào)用M2之后的代碼

托管堆

我們假定有這兩個(gè)類的定義

image.png

window進(jìn)程已經(jīng)啟動(dòng)扫沼,托管堆已初始化出爹,已經(jīng)創(chuàng)建了一個(gè)線程庄吼。該線程已經(jīng)調(diào)用了一些代碼,現(xiàn)在馬上要調(diào)用M3严就。

image.png

這時(shí)候CLR要做的事情

  • 確保M3內(nèi)部引用的所有類型的程序集都已加載
  • 利用程序集的元數(shù)據(jù)創(chuàng)建類型對象(Type Object表示類型本身)

類型對象包括

  • 類型對象指針(Type Object Pointer)和同步塊索引(sync block index)
  • 靜態(tài)字段
  • 方法表
image.png

當(dāng)前面的事情做好后总寻,開始執(zhí)行M3的本地代碼,首先為局部變量分配內(nèi)存梢为,CLR會(huì)自動(dòng)將局部變量初始化成null或0

image.png

接下來渐行,M3代碼開始構(gòu)造一個(gè)Manager實(shí)例(也就是一個(gè)Manager對象),步驟如下

  1. 初始化類型對象指針铸董,并指向與對象對應(yīng)的類型對象
  2. 初始化同步索引塊
  3. 將所有實(shí)例字段初始化
  4. new操作符會(huì)返回對象的內(nèi)存地址祟印,將之保存到變量e

對象包括

  • 類型對象指針(Type Object Pointer)和同步塊索引(sync block index)
  • 實(shí)例字段


    image.png

M3下一行調(diào)用Employee的靜態(tài)方法Lookup。調(diào)用靜態(tài)方法的步驟

  1. CLR會(huì)定位與定義靜態(tài)方法的類型相對應(yīng)的類型對象
  2. JIT編譯器在類型對象的方法表找到該方法粟害,對方法進(jìn)行JIT進(jìn)行編譯(如果需要的話)蕴忆,再調(diào)用JIT編譯的代碼
  3. Lookup方法在堆上構(gòu)造一個(gè)新的Manager對象,并返回地址
  4. M3將地址存到變量e

需要注意的是我磁,變量e已經(jīng)引用了新的對象孽文。原來的對象沒有變量引用,GC將會(huì)對其自動(dòng)進(jìn)行回收夺艰。

image.png

M3的下一行代碼調(diào)用虛實(shí)例方法GenProgressReport芋哭。調(diào)用一個(gè)虛實(shí)例方法時(shí),JIT編譯器要在方法中生成一些額外的代碼郁副;方法每次調(diào)用時(shí)减牺,都會(huì)調(diào)用這些代碼。

  1. 檢查發(fā)出調(diào)用的變量存谎,跟隨地址來到發(fā)出調(diào)用的對象拔疚,檢查對象的類型對象指針,找到類型對象既荚,并在方法表中定位該方法稚失。(和非虛方法的區(qū)別:非虛關(guān)心的是變量e的類型,而虛關(guān)心的是變量e所指向的對象的類型)
  2. JIT編譯器在類型對象的方法表找到該方法恰聘,對方法進(jìn)行JIT進(jìn)行編譯(如果需要的話)句各,再調(diào)用JIT編譯的代碼
image.png

Manager和Employee類型對象也有類型對象指針,那這些指針是指向哪里的呢晴叨?實(shí)際上凿宾,CLR在進(jìn)程運(yùn)行時(shí),會(huì)為System.Type創(chuàng)建一個(gè)特殊的類型對象兼蕊,Manager和Employee的類型對象的類型對象指針都指向它初厚。System.Type的類型對象指針就指向自身。
System.Obejct有一個(gè)GetType方法孙技,返回類型對象指針产禾,這樣就可以判斷系統(tǒng)中任何對象(也包括類型對象)的類型了排作。

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市下愈,隨后出現(xiàn)的幾起案子纽绍,更是在濱河造成了極大的恐慌,老刑警劉巖势似,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拌夏,死亡現(xiàn)場離奇詭異,居然都是意外死亡履因,警方通過查閱死者的電腦和手機(jī)障簿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栅迄,“玉大人站故,你說我怎么就攤上這事∫阌撸” “怎么了西篓?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長憋活。 經(jīng)常有香客問我岂津,道長,這世上最難降的妖魔是什么悦即? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任吮成,我火速辦了婚禮,結(jié)果婚禮上辜梳,老公的妹妹穿的比我還像新娘粱甫。我一直安慰自己,他們只是感情好作瞄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布茶宵。 她就那樣靜靜地躺著,像睡著了一般宗挥。 火紅的嫁衣襯著肌膚如雪节预。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天属韧,我揣著相機(jī)與錄音,去河邊找鬼蛤吓。 笑死宵喂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的会傲。 我是一名探鬼主播锅棕,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拙泽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了裸燎?” 一聲冷哼從身側(cè)響起顾瞻,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎德绿,沒想到半個(gè)月后荷荤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡移稳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年蕴纳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片个粱。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡古毛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出都许,到底是詐尸還是另有隱情稻薇,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布胶征,位于F島的核電站塞椎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏弧烤。R本人自食惡果不足惜忱屑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望暇昂。 院中可真熱鬧莺戒,春花似錦、人聲如沸急波。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澄暮。三九已至名段,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泣懊,已是汗流浹背伸辟。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留馍刮,地道東北人信夫。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親静稻。 傳聞我的和親對象是個(gè)殘疾皇子警没,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 本章內(nèi)容: 1.所有類型都從System.Object派生2.類型轉(zhuǎn)換3.命名空間和程序集4.運(yùn)行時(shí)的相互關(guān)系 4...
    clihen閱讀 401評論 0 0
  • [TOC] 內(nèi)存管理 一、托管堆基礎(chǔ) 在面向?qū)ο笾姓裢澹總€(gè)類型代表一種可使用的資源杀迹,要使用該資源,必須為代表資源的類...
    _秦同學(xué)_閱讀 3,808評論 0 3
  • 第二部分 自動(dòng)內(nèi)存管理機(jī)制 第二章 java內(nèi)存異常與內(nèi)存溢出異常 運(yùn)行數(shù)據(jù)區(qū)域 程序計(jì)數(shù)器:當(dāng)前線程所執(zhí)行的字節(jié)...
    小明oh閱讀 1,172評論 0 2
  • 《深入理解Java虛擬機(jī)》筆記_第一遍 先取看完這本書(JVM)后必須掌握的部分押搪。 第一部分 走近 Java 從傳...
    xiaogmail閱讀 5,097評論 1 34
  • 所有知識(shí)點(diǎn)已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)树酪? 在 Jav...
    侯蛋蛋_閱讀 2,440評論 1 4