已閱讀5頁(yè),還剩1頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
本文將介紹以下內(nèi)容: 類型的基本概念 值類型深入 引用類型深入 值類型與引用類型的比較及應(yīng)用 1.引言買(mǎi)了新本本,忙了好幾天系統(tǒng),終于開(kāi)始了對(duì)值類型和引用類型做個(gè)全面的講述了,本系列開(kāi)篇之時(shí)就是因?yàn)橄雽?xiě)這個(gè)主題,才有了寫(xiě)個(gè)系列的想法。所以對(duì) 值類型和引用類型的分析,是我最想成文的一篇,其原因是過(guò)去的學(xué)習(xí)過(guò)程中我就是從這個(gè)主題開(kāi)始,喜歡以IL語(yǔ)言來(lái)分析執(zhí)行,也喜好從底層的過(guò)程來(lái)深入了 解。這對(duì)我來(lái)說(shuō),似乎是一件找到了有效提高的方法,所以想寫(xiě)的沖動(dòng)就沒(méi)有停過(guò),旨在以有效的方式來(lái)分享所得。同時(shí),我也認(rèn)為,對(duì)值類型和引用類型的把握, 是理解語(yǔ)言基礎(chǔ)環(huán)節(jié)的關(guān)鍵主題,有必要花力氣來(lái)了解和深入。2. 一切從內(nèi)存開(kāi)始 2.1 基本概念 從上回第七回:品味類型-從通用類型系統(tǒng)開(kāi)始我們知道,CLR支持兩種基本類型:值類型和引用類型。因此,還是把MSDN這張經(jīng)典視圖拿出來(lái)做個(gè)鋪墊。 值類型(Value Type),值類型實(shí)例通常分配在線程的堆棧(stack)上,并且不包含任何指向?qū)嵗龜?shù)據(jù)的指針,因?yàn)樽兞勘旧砭桶似鋵?shí)例數(shù)據(jù)。其在MSDN的定義 為值類型直接包含它們的數(shù)據(jù),值類型的實(shí)例要么在堆棧上,要么內(nèi)聯(lián)在結(jié)構(gòu)中。我們由上圖可知,值類型主要包括簡(jiǎn)單類型、結(jié)構(gòu)體類型和枚舉類型等。通常聲明 為以下類型:int、char、float、long、bool、double、struct、enum、short、byte、decimal、 sbyte、uint、ulong、ushort等時(shí),該變量即為值類型。 引用類型(Reference Type),引用類型實(shí)例分配在托管堆(managed heap)上,變量保存了實(shí)例數(shù)據(jù)的內(nèi)存引用。其在MSDN中的定義為引用類型存儲(chǔ)對(duì)值的內(nèi)存地址的引用,位于堆上。我們由上圖可知,引用類型可以是自描 述類型、指針類型或接口類型。而自描述類型進(jìn)一步細(xì)分成數(shù)組和類類型。類類型是則可以是用戶定義的類、裝箱的值類型和委托。通常聲明為以下類 型:class、interface、delegate、object、string以及其他的自定義引用類型時(shí),該變量即為引用類型。 下面簡(jiǎn)單的列出我們類型的進(jìn)一步細(xì)分,數(shù)據(jù)來(lái)自MSDN,為的是給我們的概念中有清晰的類型概念,這是最基礎(chǔ)也是最必須的內(nèi)容。 2.2 內(nèi)存深入 2.2.1. 內(nèi)存機(jī)制 那么.NET的內(nèi)存分配機(jī)制如何呢? 數(shù)據(jù)在內(nèi)存中的分配位置,取決于該變量的數(shù)據(jù)類型。由上可知,值類型通常分配在線程的堆棧上,而引用類型通常分配在托管堆上,由GC來(lái)控制其回收。例如,現(xiàn)在有MyStruct和MyClass分別代表一個(gè)結(jié)構(gòu)體和一個(gè)類,如下: usingSystem;publicclassTeststaticvoidMain()/定義值類型和引用類型,并完成初始化MyStructmyStruct=newMyStruct();MyClassmyClass=newMyClass();/定義另一個(gè)值類型和引用類型,/以便了解其內(nèi)存區(qū)別MyStructmyStruct2=newMyStruct();myStruct2=myStruct;MyClassmyClass2=newMyClass();myClass2=myClass;在上述的過(guò)程中,我們分別定義了值類型變量myStruct和引用類型變量myClass,并使用new操作符完成內(nèi)存分配和初始化操作,此處new的區(qū)別可以詳見(jiàn)第五回:深入淺出關(guān)鍵字-把new說(shuō)透 的論述,在此不做進(jìn)一步描述。而我們?cè)诖藦?qiáng)調(diào)的是myStruct和myClass兩個(gè)變量在內(nèi)存分配方面的區(qū)別,還是以一個(gè)簡(jiǎn)明的圖來(lái)展示一下: 我們知道,每個(gè)變量或者程序都有其堆棧,不同的變量不能共有同一個(gè)堆棧地址,因此myStruct和myStruct2 在堆棧中一定占用了不同的堆棧地址,盡管經(jīng)過(guò)了變量的傳遞,實(shí)際的內(nèi)存還是分配在不同的地址上,如果我們?cè)賹?duì)myStruct2變量改變時(shí),顯然不會(huì)影響 到myStruct的數(shù)據(jù)。從圖中我們還可以顯而易見(jiàn)的看出,myStruct在堆棧中包含其實(shí)例數(shù)據(jù),而myClass在堆棧中只是保存了其實(shí)例數(shù)據(jù)的 引用地址,實(shí)際的數(shù)據(jù)保存在托管堆中。因此,就有可能不同的變量保存了同一地址的數(shù)據(jù)引用,當(dāng)數(shù)據(jù)從一個(gè)引用類型變量傳遞到另一個(gè)相同類型的引用類型變量 時(shí),傳遞的是其引用地址而不是實(shí)際的數(shù)據(jù),因此一個(gè)變量的改變會(huì)影響另一個(gè)變量的值。從上面的分析就可以明白的知道這樣一個(gè)簡(jiǎn)單的道理:值類型和引用類型 在內(nèi)存中的分配區(qū)別是決定其應(yīng)用不同的根本原因,由此我們就可以很容易的解釋為什么參數(shù)傳遞時(shí),按值傳遞不會(huì)改變形參值,而按址傳遞會(huì)改變行參的值,道理 正在于此。 對(duì)于內(nèi)存分配的更詳細(xì)位置,可以描述如下: 值類型變量做為局部變量時(shí),該實(shí)例將被創(chuàng)建在堆棧上;而如果值類型變量作為類型的成員變量時(shí),它將作為類型實(shí)例數(shù)據(jù)的一部分,同該類型的其他字段都保存在托管堆上,這點(diǎn)我們將在接下來(lái)的嵌套結(jié)構(gòu)部分來(lái)詳細(xì)說(shuō)明。 引用類型變量數(shù)據(jù)保存在托管堆上,但是根據(jù)實(shí)例的大小有所區(qū)別,如下:如果實(shí)例的大小小于85000Byte時(shí),則該實(shí)例將創(chuàng)建在GC堆上;而當(dāng)實(shí)例大小大于等于85000byte時(shí),則該實(shí)例創(chuàng)建在LOH(Large Object Heap)堆上。更詳細(xì)的分析,我推薦類型實(shí)例的創(chuàng)建位置、托管對(duì)象在托管堆上的結(jié)構(gòu)。2.2.2. 嵌套結(jié)構(gòu) 嵌套結(jié)構(gòu)就是在值類型中嵌套定義了引用類型,或者在引用類型變量中嵌套定義了值類型,相信園子中關(guān)于這一話題的論述和關(guān)注都不是很多。因此我們很有必要發(fā)揮一下,在此就順藤摸瓜,從上文對(duì).NET的內(nèi)存機(jī)制著手來(lái)理解會(huì)水到渠成。 引用類型嵌套值類型 值類型如果嵌套在引用類型時(shí),也就是值類型在內(nèi)聯(lián)的結(jié)構(gòu)中時(shí),其內(nèi)存分配是什么樣子呢? 其實(shí)很簡(jiǎn)單,例如類的私有字段如果為值類型,那它作為引用類型實(shí)例的一部分,也分配在托管堆上。例如: publicclassNestedValueinRef/aInt做為引用類型的一部分將分配在托管堆上privateintaInt;publicNestedValueinRef/aChar則分配在該段代碼的線程棧上charachar=a;其內(nèi)存分配圖可以表示為: 值類型嵌套引用類型 引用類型嵌套在值類型時(shí),內(nèi)存的分配情況為:該引用類型將作為值類型的成員變量,堆棧上將保存該成員的引用,而成員的實(shí)際數(shù)據(jù)還是保存在托管堆中。例如:publicstructNestedRefinValuepublicMyClassmyClass;publicNestedRefinValuemyClass.X=1;myClass.Y=2;其內(nèi)存分配圖可以表示為:2.2.3. 一個(gè)簡(jiǎn)單的討論通過(guò)上面的分析,如果我們現(xiàn)在有如下的執(zhí)行時(shí):AType myType = new AType10;試問(wèn):如果AType是值類型,則分配了多少內(nèi)存;而如果AType是引用類型時(shí),又分配了多少內(nèi)存?我們的分析如下:根據(jù)CRL的內(nèi)存機(jī)制,我們知道如果ATpye為Int32類型,則表示其元素是值類型,而數(shù)組本身為引用類型,myType將保 存指向托管堆中的一塊大小為410byte的內(nèi)存地址,并且將所有的元素賦值為0;而如果AType為自定義的引用類型,則會(huì)只做一次
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版?zhèn)€體廂貨車(chē)出租及車(chē)輛監(jiān)控系統(tǒng)合同3篇
- 2025版土地居間業(yè)務(wù)規(guī)范化合同書(shū)(2025版)6篇
- 2025版建筑塑料材料買(mǎi)賣(mài)合同范本解讀3篇
- 《手機(jī)送分析》課件
- 【中學(xué)課件】香港和澳門(mén)
- 二零二五版汽車(chē)銷售退換貨處理合同模板2篇
- 二零二五版智慧城市建設(shè)項(xiàng)目工程勘察設(shè)計(jì)勞務(wù)分包合同3篇
- 家用紡織品的消費(fèi)趨勢(shì)與市場(chǎng)需求預(yù)測(cè)考核試卷
- 《波爾多液配制》課件
- 2025版事業(yè)單位聘用合同起草與審查要點(diǎn)3篇
- 2024-2025學(xué)年山東省濰坊市高一上冊(cè)1月期末考試數(shù)學(xué)檢測(cè)試題(附解析)
- 數(shù)學(xué)-湖南省新高考教學(xué)教研聯(lián)盟(長(zhǎng)郡二十校聯(lián)盟)2024-2025學(xué)年2025屆高三上學(xué)期第一次預(yù)熱演練試題和答案
- 決勝中層:中層管理者的九項(xiàng)修煉-記錄
- 幼兒園人民幣啟蒙教育方案
- 高考介詞練習(xí)(附答案)
- 單位就業(yè)人員登記表
- 衛(wèi)生監(jiān)督協(xié)管-醫(yī)療機(jī)構(gòu)監(jiān)督
- 記錄片21世紀(jì)禁愛(ài)指南
- 腰椎間盤(pán)的診斷證明書(shū)
- 移動(dòng)商務(wù)內(nèi)容運(yùn)營(yíng)(吳洪貴)任務(wù)七 裂變傳播
- 單級(jí)倒立擺系統(tǒng)建模與控制器設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論