天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

[你必須知道的.NET] 第十九回:對(duì)象創(chuàng)建始末(下)

系列文章導(dǎo)航:

[你必須知道的.NET] 開篇有益

[你必須知道的.NET] 第一回:恩怨情仇:is和as

[你必須知道的.NET] 第二回:對(duì)抽象編程:接口和抽象類

[你必須知道的.NET] 第三回:歷史糾葛:特性和屬性

[你必須知道的.NET] 第四回:后來居上:class和struct

[你必須知道的.NET] 第五回:深入淺出關(guān)鍵字---把new說透

[你必須知道的.NET] 第六回:深入淺出關(guān)鍵字---base和this

[你必須知道的.NET] 第七回:品味類型---從通用類型系統(tǒng)開始

[你必須知道的.NET] 第八回:品味類型---值類型與引用類型(上)-內(nèi)存有理

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

[你必須知道的.NET] 第十回:品味類型---值類型與引用類型(下)-應(yīng)用征途

[你必須知道的.NET] 第十一回:參數(shù)之惑---傳遞的藝術(shù)(上)

[你必須知道的.NET] 第十二回:參數(shù)之惑---傳遞的藝術(shù)(下)

[你必須知道的.NET] 第十三回:從Hello, world開始認(rèn)識(shí)IL

[你必須知道的.NET] 第十四回:認(rèn)識(shí)IL代碼---從開始到現(xiàn)在

[你必須知道的.NET] 第十五回:繼承本質(zhì)論

[你必須知道的.NET] 第十六回:深入淺出關(guān)鍵字---using全接觸

[你必須知道的.NET] 第十七回:貌合神離:覆寫和重載

[你必須知道的.NET] 第十八回:對(duì)象創(chuàng)建始末(上)

[你必須知道的.NET] 第十九回:對(duì)象創(chuàng)建始末(下)

[你必須知道的.NET]第二十回:學(xué)習(xí)方法論

[你必須知道的.NET]第二十一回:認(rèn)識(shí)全面的null

[你必須知道的.NET]第二十二回:字符串駐留(上)---帶著問題思考

[你必須知道的.NET]第三十二回,深入.NET 4.0之,Tuple一二


  本文將介紹以下內(nèi)容:

  • 對(duì)象的創(chuàng)建過程

  • 內(nèi)存分配分析

  • 內(nèi)存布局研究

  接上回[第十八回:對(duì)象創(chuàng)建始末(上)],繼續(xù)對(duì)對(duì)象創(chuàng)建話題的討論>>>

  2.2 托管堆的內(nèi)存分配機(jī)制

  引用類型的實(shí)例分配于托管堆上,而線程棧卻是對(duì)象生命周期開始的地方。對(duì)32位處理器來說,應(yīng)用程序完成進(jìn)程初始化后,CLR將在進(jìn)程的可用地址空間上分配一塊保留的地址空間,它是進(jìn)程(每個(gè)進(jìn)程可使用4GB)中可用地址空間上的一塊內(nèi)存區(qū)域,但并不對(duì)應(yīng)于任何物理內(nèi)存,這塊地址空間即是托管堆。

  托管堆又根據(jù)存儲(chǔ)信息的不同劃分為多個(gè)區(qū)域,其中最重要的是垃圾回收堆(GC Heap)和加載堆(Loader Heap),GC Heap用于存儲(chǔ)對(duì)象實(shí)例,受GC管理;Loader Heap又分為High-Frequency Heap、Low-Frequency Heap和Stub Heap,不同的堆上又存儲(chǔ)不同的信息。Loader Heap最重要的信息就是元數(shù)據(jù)相關(guān)的信息,也就是Type對(duì)象,每個(gè)Type在Loader Heap上體現(xiàn)為一個(gè)Method Table(方法表),而Method Table中則記錄了存儲(chǔ)的元數(shù)據(jù)信息,例如基類型、靜態(tài)字段、實(shí)現(xiàn)的接口、所有的方法等等。Loader Heap不受GC控制,其生命周期為從創(chuàng)建到AppDomain卸載。

  在進(jìn)入實(shí)際的內(nèi)存分配分析之前,有必要對(duì)幾個(gè)基本概念做以交代,以便更好的在接下來的分析中展開討論。

  • TypeHandle,類型句柄,指向?qū)?yīng)實(shí)例的方法表,每個(gè)對(duì)象創(chuàng)建時(shí)都包含該附加成員,并且占用4個(gè)字節(jié)的內(nèi)存空間。我們知道,每個(gè)類型都對(duì)應(yīng)于一個(gè)方法表,方法表創(chuàng)建于編譯時(shí),主要包含了類型的特征信息、實(shí)現(xiàn)的接口數(shù)目、方法表的slot數(shù)目等。

  • SyncBlockIndex,用于線程同步,每個(gè)對(duì)象創(chuàng)建時(shí)也包含該附加成員,它指向一塊被稱為Synchronization Block的內(nèi)存塊,用于管理對(duì)象同步,同樣占用4個(gè)字節(jié)的內(nèi)存空間。

  • NextObjPtr,由托管堆維護(hù)的一個(gè)指針,用于標(biāo)識(shí)下一個(gè)新建對(duì)象分配時(shí)在托管堆中所處的位置。CLR初始化時(shí),NextObjPtr位于托管堆的基地址。

  因此,我們對(duì)引用類型分配過程應(yīng)該有個(gè)基本的了解,由于本篇示例中FileStream類型的繼承關(guān)系相對(duì)復(fù)雜,在此本文實(shí)現(xiàn)一個(gè)相對(duì)簡(jiǎn)單的類型來做說明:

Code

系列文章導(dǎo)航:

[你必須知道的.NET] 開篇有益

[你必須知道的.NET] 第一回:恩怨情仇:is和as

[你必須知道的.NET] 第二回:對(duì)抽象編程:接口和抽象類

[你必須知道的.NET] 第三回:歷史糾葛:特性和屬性

[你必須知道的.NET] 第四回:后來居上:class和struct

[你必須知道的.NET] 第五回:深入淺出關(guān)鍵字---把new說透

[你必須知道的.NET] 第六回:深入淺出關(guān)鍵字---base和this

[你必須知道的.NET] 第七回:品味類型---從通用類型系統(tǒng)開始

[你必須知道的.NET] 第八回:品味類型---值類型與引用類型(上)-內(nèi)存有理

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

[你必須知道的.NET] 第十回:品味類型---值類型與引用類型(下)-應(yīng)用征途

[你必須知道的.NET] 第十一回:參數(shù)之惑---傳遞的藝術(shù)(上)

[你必須知道的.NET] 第十二回:參數(shù)之惑---傳遞的藝術(shù)(下)

[你必須知道的.NET] 第十三回:從Hello, world開始認(rèn)識(shí)IL

[你必須知道的.NET] 第十四回:認(rèn)識(shí)IL代碼---從開始到現(xiàn)在

[你必須知道的.NET] 第十五回:繼承本質(zhì)論

[你必須知道的.NET] 第十六回:深入淺出關(guān)鍵字---using全接觸

[你必須知道的.NET] 第十七回:貌合神離:覆寫和重載

[你必須知道的.NET] 第十八回:對(duì)象創(chuàng)建始末(上)

[你必須知道的.NET] 第十九回:對(duì)象創(chuàng)建始末(下)

[你必須知道的.NET]第二十回:學(xué)習(xí)方法論

[你必須知道的.NET]第二十一回:認(rèn)識(shí)全面的null

[你必須知道的.NET]第二十二回:字符串駐留(上)---帶著問題思考

[你必須知道的.NET]第三十二回,深入.NET 4.0之,Tuple一二


另外,實(shí)例字段的存儲(chǔ)是有順序的,由上到下依次排列,父類在前子類在后,詳細(xì)的分析請(qǐng)參見[第十五回:繼承本質(zhì)論]。

 

  在上述操作時(shí),如果試圖分配所需空間而發(fā)現(xiàn)內(nèi)存不足時(shí),GC將啟動(dòng)垃圾收集操作來回收垃圾對(duì)象所占的內(nèi)存,我們將以后對(duì)此做詳細(xì)的分析。

  • 最后,調(diào)用對(duì)象構(gòu)造器,進(jìn)行對(duì)象初始化操作,完成創(chuàng)建過程。該構(gòu)造過程,又可細(xì)分為以下幾個(gè)環(huán)節(jié):

  (a)構(gòu)造VIPUser類型的Type對(duì)象,主要包括靜態(tài)字段、方法表、實(shí)現(xiàn)的接口等,并將其分配在上文提到托管堆的Loader Heap上。

  (b)初始化aUser的兩個(gè)附加成員:TypeHandle和SyncBlockIndex。將TypeHandle指針指向Loader Heap上的MethodTable,CLR將根據(jù)TypeHandle來定位具體的Type;將SyncBlockIndex指針指向Synchronization Block的內(nèi)存塊,用于在多線程環(huán)境下對(duì)實(shí)例對(duì)象的同步操作。

  (c)調(diào)用VIPUser的構(gòu)造器,進(jìn)行實(shí)例字段的初始化。實(shí)例初始化時(shí),會(huì)首先向上遞歸執(zhí)行父類初始化,直到完成System.Object類型的初始化,然后再返回執(zhí)行子類的初始化,直到執(zhí)行VIPUser類為止。以本例而言,初始化過程為首先執(zhí)行System.Object類,再執(zhí)行User類,最后才是VIPUser類。最終,newobj分配的托管堆的內(nèi)存地址,被傳遞給VIPUser的this參數(shù),并將其引用傳給棧上聲明的aUser。

  上述過程,基本完成了一個(gè)引用類型創(chuàng)建、內(nèi)存分配和初始化的整個(gè)流程,然而該過程只能看作是一個(gè)簡(jiǎn)化的描述,實(shí)際的執(zhí)行過程更加復(fù)雜,涉及到一系列細(xì)化的過程和操作。對(duì)象創(chuàng)建并初始化之后,內(nèi)存的布局,可以表示為:

  由上文的分析可知,在托管堆中增加新的實(shí)例對(duì)象,只是將NextObjPtr指針增加一定的數(shù)值,再次新增的對(duì)象將分配在當(dāng)前NextObjPtr指向的內(nèi)存空間,因此在托管堆棧中,連續(xù)分配的對(duì)象在內(nèi)存中一定是連續(xù)的,這種分配機(jī)制非常高效。

  2.3 必要的補(bǔ)充

  有了對(duì)象創(chuàng)建的基本流程概念,下面的幾個(gè)問題時(shí)常引起大家的思考,在此本文一并做以探索:

  • 值類型中的引用類型字段和引用類型中的值類型字段,其分配情況又是如何?

  這一思考其實(shí)是一個(gè)問題的兩個(gè)方面:對(duì)于值類型嵌套引用類型的情況,引用類型變量作為值類型的成員變量,在堆棧上保存該成員的引用,而實(shí)際的引用類型仍然保存在GC堆上;對(duì)于引用類型嵌套值類型的情況,則該值類型字段將作為引用類型實(shí)例的一部分保存在GC堆上。在[ 第八回:品味類型---值類型與引用類型(上)-內(nèi)存有理]一文對(duì)這種嵌套結(jié)構(gòu),有較詳細(xì)的分析。對(duì)于值類型,你只要記著它總是分配在聲明它的地方。

  • 方法保存在Loader Heap的MethodTable中,那么方法調(diào)用時(shí)又是怎么樣的過程?

  如上文所言,MethodTable中包含了類型的元數(shù)據(jù)信息,類在加載時(shí)會(huì)在Loader Heap上創(chuàng)建這些信息,一個(gè)類型在內(nèi)存中對(duì)應(yīng)一份MethodTable,其中包含了所有的方法、靜態(tài)字段和實(shí)現(xiàn)的接口信息等。對(duì)象實(shí)例的TypeHandle在實(shí)例創(chuàng)建時(shí),將指向MethodTable開始位置的偏移處(默認(rèn)偏移12Byte),通過對(duì)象實(shí)例調(diào)用某個(gè)方法時(shí),CLR根據(jù)TypeHandle可以找到對(duì)應(yīng)的MethodTable,進(jìn)而可以定位到具體的方法,再通過JIT Compiler將IL指令編譯為本地CPU指令,該指令將保存在一個(gè)動(dòng)態(tài)內(nèi)存中,然后在該內(nèi)存地址上執(zhí)行該方法,同時(shí)該CPU指令被保存起來用于下一次的執(zhí)行。

  在MethodTable中,包含一個(gè)Method Slot Table,稱為方法槽表,該表是一個(gè)基于方法實(shí)現(xiàn)的線性鏈表,并按照以下順序排列:繼承的虛方法,引入的虛方法,實(shí)例方法和靜態(tài)方法。方法表在創(chuàng)建時(shí),將按照繼承層次向上搜索父類,直到System.Object類型,如果子類覆寫了父類方法,則將會(huì)以子類方法覆蓋父類虛方法。關(guān)于方法表的創(chuàng)建過程,可以參考[第十五回:繼承本質(zhì)論]中的描述。

  • 靜態(tài)字段的內(nèi)存分配和釋放,又有何不同?

  靜態(tài)字段也保存在方法表中,位于方法表的槽數(shù)組后,其生命周期為從創(chuàng)建到AppDomain卸載。因此一個(gè)類型無論創(chuàng)建多少個(gè)對(duì)象,其靜態(tài)字段在內(nèi)存中也只有一份。靜態(tài)字段只能由靜態(tài)構(gòu)造函數(shù)進(jìn)行初始化,靜態(tài)構(gòu)造函數(shù)確保在類型任何對(duì)象創(chuàng)建前,或者在任何靜態(tài)字段或方法被引用前執(zhí)行,其詳細(xì)的執(zhí)行順序請(qǐng)參考相關(guān)討論。

  3. 結(jié)論

  對(duì)象創(chuàng)建過程的了解,是從底層接觸CLR運(yùn)行機(jī)制的入口,也是認(rèn)識(shí).NET自動(dòng)內(nèi)存管理的關(guān)鍵。通過本文的詳細(xì)論述,關(guān)于對(duì)象的創(chuàng)建、內(nèi)存分配、初始化過程和方法調(diào)用等技術(shù)都會(huì)建立一個(gè)相對(duì)全面的理解,同時(shí)也清楚的把握了線程棧和托管堆的執(zhí)行機(jī)制。

  對(duì)象總是有生有滅,本文簡(jiǎn)述其生,這是個(gè)偉大的開始。 
                            

                              © 2007 Anytao.com

NET技術(shù)[你必須知道的.NET] 第十九回:對(duì)象創(chuàng)建始末(下),轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 主播蜜汁丝袜精品自拍 | 香蕉97超级碰碰碰碰碰久 | 国产精品爆乳尤物99精品 | 亚洲不卡高清免v无码屋 | 973午夜伦伦电影论片 | 国产全肉乱妇杂乱视频 | 国产在线精品视频免费观看 | 青青伊人国产 | 亚洲精品色情APP在线下载观看 | 经典三级四虎在线观看 | 老板吻我下身好爽到高潮 | 国产亚洲人成网站在线观看播放 | 国产精品美女WWW爽爽爽视频 | 国产精品久久久久久影院 | 无码AV熟妇素人内射V在线 | 亚洲中文日韩日本在线视频 | 俄罗斯aaaa一级毛片 | jizzzz亚洲丰满xxxx| 国产喷水1区2区3区咪咪爱AV | 国产精品久久久久久人妻香蕉 | 久久国产精品福利影集 | 九九热精品免费观看 | 国产欧美第一页 | 一抽一出BGM免费50分动漫 | 色欲国产麻豆一精品一AV一免费 | 青青草AV国产精品 | 野花视频在线观看免费 | 色宅男看片午夜大片免费看 | 天堂Av亚洲欧美日韩国产综合 | 99热这里只有精品6 99热这里只有精品 99热这里只有的精品 | 日日干夜夜爱 | 亚洲电影不卡 | 亚洲精品第二页 | 翁公咬着小娇乳H边走边欢A | 国精产品999一区二区三区有限 | 久久高清免费视频 | 久久aa毛片免费播放嗯啊 | 老师的玉足高跟鞋满足我 | 亚洲精品无码不卡在线播HE | 伊人免费在线 | 99re精品视频在线播放视频 |