品味類型——值類型與引用類型.doc_第1頁
品味類型——值類型與引用類型.doc_第2頁
品味類型——值類型與引用類型.doc_第3頁
品味類型——值類型與引用類型.doc_第4頁
品味類型——值類型與引用類型.doc_第5頁
已閱讀5頁,還剩1頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

本文將介紹以下內(nèi)容: 類型的基本概念 值類型深入 引用類型深入 值類型與引用類型的比較及應(yīng)用 1.引言買了新本本,忙了好幾天系統(tǒng),終于開始了對值類型和引用類型做個全面的講述了,本系列開篇之時就是因為想寫這個主題,才有了寫個系列的想法。所以對 值類型和引用類型的分析,是我最想成文的一篇,其原因是過去的學習過程中我就是從這個主題開始,喜歡以IL語言來分析執(zhí)行,也喜好從底層的過程來深入了 解。這對我來說,似乎是一件找到了有效提高的方法,所以想寫的沖動就沒有停過,旨在以有效的方式來分享所得。同時,我也認為,對值類型和引用類型的把握, 是理解語言基礎(chǔ)環(huán)節(jié)的關(guān)鍵主題,有必要花力氣來了解和深入。2. 一切從內(nèi)存開始 2.1 基本概念 從上回第七回:品味類型-從通用類型系統(tǒng)開始我們知道,CLR支持兩種基本類型:值類型和引用類型。因此,還是把MSDN這張經(jīng)典視圖拿出來做個鋪墊。 值類型(Value Type),值類型實例通常分配在線程的堆棧(stack)上,并且不包含任何指向?qū)嵗龜?shù)據(jù)的指針,因為變量本身就包含了其實例數(shù)據(jù)。其在MSDN的定義 為值類型直接包含它們的數(shù)據(jù),值類型的實例要么在堆棧上,要么內(nèi)聯(lián)在結(jié)構(gòu)中。我們由上圖可知,值類型主要包括簡單類型、結(jié)構(gòu)體類型和枚舉類型等。通常聲明 為以下類型:int、char、float、long、bool、double、struct、enum、short、byte、decimal、 sbyte、uint、ulong、ushort等時,該變量即為值類型。 引用類型(Reference Type),引用類型實例分配在托管堆(managed heap)上,變量保存了實例數(shù)據(jù)的內(nèi)存引用。其在MSDN中的定義為引用類型存儲對值的內(nèi)存地址的引用,位于堆上。我們由上圖可知,引用類型可以是自描 述類型、指針類型或接口類型。而自描述類型進一步細分成數(shù)組和類類型。類類型是則可以是用戶定義的類、裝箱的值類型和委托。通常聲明為以下類 型:class、interface、delegate、object、string以及其他的自定義引用類型時,該變量即為引用類型。 下面簡單的列出我們類型的進一步細分,數(shù)據(jù)來自MSDN,為的是給我們的概念中有清晰的類型概念,這是最基礎(chǔ)也是最必須的內(nèi)容。 2.2 內(nèi)存深入 2.2.1. 內(nèi)存機制 那么.NET的內(nèi)存分配機制如何呢? 數(shù)據(jù)在內(nèi)存中的分配位置,取決于該變量的數(shù)據(jù)類型。由上可知,值類型通常分配在線程的堆棧上,而引用類型通常分配在托管堆上,由GC來控制其回收。例如,現(xiàn)在有MyStruct和MyClass分別代表一個結(jié)構(gòu)體和一個類,如下: usingSystem;publicclassTeststaticvoidMain()/定義值類型和引用類型,并完成初始化MyStructmyStruct=newMyStruct();MyClassmyClass=newMyClass();/定義另一個值類型和引用類型,/以便了解其內(nèi)存區(qū)別MyStructmyStruct2=newMyStruct();myStruct2=myStruct;MyClassmyClass2=newMyClass();myClass2=myClass;在上述的過程中,我們分別定義了值類型變量myStruct和引用類型變量myClass,并使用new操作符完成內(nèi)存分配和初始化操作,此處new的區(qū)別可以詳見第五回:深入淺出關(guān)鍵字-把new說透 的論述,在此不做進一步描述。而我們在此強調(diào)的是myStruct和myClass兩個變量在內(nèi)存分配方面的區(qū)別,還是以一個簡明的圖來展示一下: 我們知道,每個變量或者程序都有其堆棧,不同的變量不能共有同一個堆棧地址,因此myStruct和myStruct2 在堆棧中一定占用了不同的堆棧地址,盡管經(jīng)過了變量的傳遞,實際的內(nèi)存還是分配在不同的地址上,如果我們再對myStruct2變量改變時,顯然不會影響 到myStruct的數(shù)據(jù)。從圖中我們還可以顯而易見的看出,myStruct在堆棧中包含其實例數(shù)據(jù),而myClass在堆棧中只是保存了其實例數(shù)據(jù)的 引用地址,實際的數(shù)據(jù)保存在托管堆中。因此,就有可能不同的變量保存了同一地址的數(shù)據(jù)引用,當數(shù)據(jù)從一個引用類型變量傳遞到另一個相同類型的引用類型變量 時,傳遞的是其引用地址而不是實際的數(shù)據(jù),因此一個變量的改變會影響另一個變量的值。從上面的分析就可以明白的知道這樣一個簡單的道理:值類型和引用類型 在內(nèi)存中的分配區(qū)別是決定其應(yīng)用不同的根本原因,由此我們就可以很容易的解釋為什么參數(shù)傳遞時,按值傳遞不會改變形參值,而按址傳遞會改變行參的值,道理 正在于此。 對于內(nèi)存分配的更詳細位置,可以描述如下: 值類型變量做為局部變量時,該實例將被創(chuàng)建在堆棧上;而如果值類型變量作為類型的成員變量時,它將作為類型實例數(shù)據(jù)的一部分,同該類型的其他字段都保存在托管堆上,這點我們將在接下來的嵌套結(jié)構(gòu)部分來詳細說明。 引用類型變量數(shù)據(jù)保存在托管堆上,但是根據(jù)實例的大小有所區(qū)別,如下:如果實例的大小小于85000Byte時,則該實例將創(chuàng)建在GC堆上;而當實例大小大于等于85000byte時,則該實例創(chuàng)建在LOH(Large Object Heap)堆上。更詳細的分析,我推薦類型實例的創(chuàng)建位置、托管對象在托管堆上的結(jié)構(gòu)。2.2.2. 嵌套結(jié)構(gòu) 嵌套結(jié)構(gòu)就是在值類型中嵌套定義了引用類型,或者在引用類型變量中嵌套定義了值類型,相信園子中關(guān)于這一話題的論述和關(guān)注都不是很多。因此我們很有必要發(fā)揮一下,在此就順藤摸瓜,從上文對.NET的內(nèi)存機制著手來理解會水到渠成。 引用類型嵌套值類型 值類型如果嵌套在引用類型時,也就是值類型在內(nèi)聯(lián)的結(jié)構(gòu)中時,其內(nèi)存分配是什么樣子呢? 其實很簡單,例如類的私有字段如果為值類型,那它作為引用類型實例的一部分,也分配在托管堆上。例如: publicclassNestedValueinRef/aInt做為引用類型的一部分將分配在托管堆上privateintaInt;publicNestedValueinRef/aChar則分配在該段代碼的線程棧上charachar=a;其內(nèi)存分配圖可以表示為: 值類型嵌套引用類型 引用類型嵌套在值類型時,內(nèi)存的分配情況為:該引用類型將作為值類型的成員變量,堆棧上將保存該成員的引用,而成員的實際數(shù)據(jù)還是保存在托管堆中。例如:publicstructNestedRefinValuepublicMyClassmyClass;publicNestedRefinValuemyClass.X=1;myClass.Y=2;其內(nèi)存分配圖可以表示為:2.2.3. 一個簡單的討論通過上面的分析,如果我們現(xiàn)在有如下的執(zhí)行時:AType myType = new AType10;試問:如果AType是值類型,則分配了多少內(nèi)存;而如果AType是引用類型時,又分配了多少內(nèi)存?我們的分析如下:根據(jù)CRL的內(nèi)存機制,我們知道如果ATpye為Int32類型,則表示其元素是值類型,而數(shù)組本身為引用類型,myType將保 存指向托管堆中的一塊大小為410byte的內(nèi)存地址,并且將所有的元素賦值為0;而如果AType為自定義的引用類型,則會只做一次

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論