欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

淺析值類型與引用類型的內(nèi)存分配

系統(tǒng) 2184 0

大家都知道要學(xué)好 .NET,深入了解值類型和引用類型是必不可少的。在這里我給大家簡單分析一下它們內(nèi)存分配的區(qū)別和聯(lián)系。

在分析之前,我們先行構(gòu)造出一個(gè)最簡單的類引用類型:

        public class MyClass
{
}
      

局部變量的聲明

在我們使用類型時(shí),代碼里面必然少不了變量的聲明,我們先看一下方法內(nèi)的局部變量的聲明,請看如下代碼:

        private static void Main()
{
int i;
MyClass mc;
i = 5;
mc = new MyClass();
}
      

當(dāng)一個(gè)局部變量聲明之后,就會(huì)在棧的內(nèi)存中分配一塊內(nèi)存給這個(gè)變量,至于這塊內(nèi)存多大,里面存放什么東西,就要看這個(gè)變量是值類型還是引用類型了。

l?值類型

如果是值類型,為變量分配這塊內(nèi)存的大小就是值類型定義的大小,存放值類型自身的值(內(nèi)容)。比如,對于上面的整型變量 i,這塊內(nèi)存的大小就是 4個(gè)字節(jié)(一個(gè) int型定義的大小),如果執(zhí)行 i = 5;這行代碼,則這塊內(nèi)存的內(nèi)容就是 5(如圖 -1)。

淺析值類型與引用類型的內(nèi)存分配

對于任何值類型,無論是讀取還是寫入操作,可以一步到位,因?yàn)橹殿愋妥兞勘旧硭嫉膬?nèi)存就存放著值。

  • 引用類型

如果是引用類型,為變量分配的這塊內(nèi)存的大小,就是一個(gè)內(nèi)存指針(實(shí)例引用、對象引用)的大小(在 32位系統(tǒng)上為 4字節(jié),在 64位系統(tǒng)上為 8字節(jié))。因?yàn)樗幸妙愋偷膶?shí)例(對象、值)都是創(chuàng)建在堆上的,而這個(gè)為變量分配的內(nèi)存就存放變量對應(yīng)在堆上的實(shí)例(對象、值)的內(nèi)存首地址(內(nèi)存指針),也叫實(shí)例(對象)的引用。以圖形化的方式展現(xiàn)仿佛是變量有一條線指向著它在堆中的實(shí)例(有如圖 -2),而如果變量的類型還沒有被實(shí)例化,則為零地址( null、空引用)。

以下為執(zhí)行 mc = new MyClass ();代碼后,內(nèi)存中的示例:

淺析值類型與引用類型的內(nèi)存分配

由圖 -2可知,變量 mc中存放的是 MyClass實(shí)例(對象)的對象引用,如果需要訪問 mc實(shí)例,系統(tǒng)需要首先從 mc變量中得到實(shí)例的引用(在堆中的地址),然后用這個(gè)引用(地址)找到堆中的實(shí)例,再進(jìn)行訪問。需要至少 2步操作才可以完成實(shí)例訪問。

類型賦值

另一個(gè)常見的操作就是類型的賦值操作,即變量之間的賦值。由于值類型和引用類型的變量內(nèi)部存放的內(nèi)容不同,導(dǎo)致在變量賦值的時(shí)候,會(huì)有相同的行為而有不同的結(jié)果。

  • 值類型

請看如下代碼:

?
        private void SomeMethod()
{
int i, j;
i = 5;
j = i;
j = 10;
}
      

相信大家一定都知道最后的結(jié)果是 i:5, j:10。不過在 .NET中, int類型也是一個(gè)結(jié)構(gòu),不但可以存放整數(shù)值,還有一系列的方法和屬性可以使用,而非我們以前學(xué) C語言時(shí)的那種單純 int存放一個(gè)整數(shù)的概念。所以我們現(xiàn)在看針對 int的代碼,其實(shí)也是在看針對 struct類型的代碼。

對于值類型的賦值語句“ j = i”,請看圖 -3:

淺析值類型與引用類型的內(nèi)存分配

在執(zhí)行 j = i;語句時(shí),變量 i中的內(nèi)容被復(fù)制了一份,然后放到了變量 j中,此時(shí)變量 i和 j都有一個(gè)值為 5,同時(shí)也可以看出, i和 j的值現(xiàn)在互不相干,完全獨(dú)立,所以任意修改其中的某個(gè)變量的值,不會(huì)影響到另外一個(gè)。

  • 引用類型

請看如下代碼:

?
        private void SomeMethod()
{
MyClass x, y;
x = new MyClass();
y = x;
}
      

代碼中先對 x進(jìn)行了實(shí)例化,然后將 x賦值到 y,這段代碼的結(jié)果請看圖 -4:

淺析值類型與引用類型的內(nèi)存分配

當(dāng)執(zhí)行 y = x;代碼時(shí),變量 x中的內(nèi)容同樣復(fù)制了一份,然后放到了變量 y之中,但是因?yàn)樽兞?x中存放是一個(gè)類型實(shí)例(對象)的引用,因此這次賦值操作等同于把這個(gè)引用傳遞給了變量 y,結(jié)果就是 x和 y中的引用指向堆中同一個(gè)類型的實(shí)例(對象)。

你可以使用 x的引用去修改 MyClass實(shí)例(對象),然后用 y的引用得到修改后的 MyClass實(shí)例(對象),反之亦可,因?yàn)?x和 y引用的是同一個(gè)實(shí)例(對象)。

復(fù)雜類型的內(nèi)存布局概述

以上內(nèi)容是以值類型或者引用類型為一個(gè)整體敘述值類型和引用類型的變量聲明和賦值的情況。下面我們看看值類型和引用類型內(nèi)部含有其他類型成員變量(一般稱為字段)的情況。雖然看起來情況似乎復(fù)雜了一點(diǎn),但是只要我們可以把握住值類型的值存放在值類型變量內(nèi)部,而引用類型的值在堆中存放,引用類型的變量只存放對它實(shí)例(對象)的引用這個(gè)原則,就可以很清晰的做出分析。

  • 值類型

且看下面的類型定義代碼:

?
        public struct MyStruct
{
/* 注意:作為結(jié)構(gòu),內(nèi)部字段是不能象下面所寫那樣,在聲明時(shí)直接初始化的。
* 但這里為了節(jié)省篇幅,從表達(dá)語義的角度,直接在聲明時(shí)初始化了
* 此結(jié)構(gòu)的代碼無法通過編譯的 */
public int i = 5; //值類型
public System.Exception ex = new Exception(); //引用類型
}
      

在 MyStruct結(jié)構(gòu)中,有2個(gè)字段,一個(gè)是值類型的i變量,一個(gè)是引用類型的ex變量。這種情況下,內(nèi)存中應(yīng)該是一個(gè)什么模樣呢?

首先,變量 i和ex作為MyStruct的成員,必然存放在MyStruct實(shí)例的內(nèi)部,而變量i作為值類型,其值就存放在自身;ex作為引用類型,變量內(nèi)只存放實(shí)例(對象)的引用,而實(shí)例(對象)則在堆上創(chuàng)建,因此就有如圖-5所示:

淺析值類型與引用類型的內(nèi)存分配

  • 引用類型

且看下面的類型定義代碼:

?
        public class MyClass
{
MyStruct ms = new MyStruct();          //上面所述的MyStruct結(jié)構(gòu)
System.Random r = new Random();   //引用類型
}
      

在 MyClass中,有2個(gè)字段成員,一個(gè)是我們上面的所定義的MyStruct結(jié)構(gòu)值類型ms,另外一個(gè)是Random類類型r。

這里我們把情況再變得復(fù)雜一些了,因?yàn)?MyStruct內(nèi)部還有值類型和引用類型的字段,這時(shí)候內(nèi)存中是一幅什么景象呢?我們要記住,不管情況多么復(fù)雜,把握住值類型和引用類型的特點(diǎn),慢慢分析,總會(huì)得到正確的結(jié)果,正如圖-6所示:

淺析值類型與引用類型的內(nèi)存分配

作為引用類型的實(shí)例(對象),無論什么情況,都是在堆中的。而 MyStruct結(jié)構(gòu)作為MyClass的成員,它也在MyClass實(shí)例所占的堆內(nèi)存中,而且因?yàn)橹殿愋偷闹凳窃谧陨泶娣诺模跃褪菆D-6中看到的結(jié)果。整個(gè)圖-6,所有的值類型和引用類型的布局,都完全負(fù)責(zé)值類型和引用類型的特點(diǎn),沒有例外。

  • 總結(jié)

以前在問起值類型和引用類型有什么區(qū)別的時(shí)候,經(jīng)常聽到同學(xué)說“值類型存放在棧上,引用類型存放在堆上”。其實(shí)這么說并不嚴(yán)謹(jǐn),因?yàn)楫?dāng)值類型作為引用類型的一個(gè)成員的時(shí)候,它的值是內(nèi)嵌在引用類型實(shí)例內(nèi)部在堆上存放的。我認(rèn)為,正確的說法應(yīng)該是:值類型變量的值存放在變量內(nèi)部,而引用類型變量的值存放在堆上,變量本身存放一個(gè)指向堆中的值的引用。同時(shí)我們也可以看到在 2個(gè)變量賦值的時(shí)候,值類型和引用類型的差別,值類型將自身的值復(fù)制給對方,之后,2方互不相干;引用類型把引用復(fù)制給對方,從而雙方都指向同一個(gè)堆中的實(shí)例,其中任何一方對實(shí)例做出修改,都會(huì)在另一方的操作中得到反映。最后我們通過復(fù)雜類型的內(nèi)部成員的內(nèi)存布局情況,進(jìn)一步了解了值類型和引用類型的內(nèi)存布局情況。

?

?

淺析值類型與引用類型的內(nèi)存分配


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产成人综合网 | 亚洲精品九九 | 亚洲免费在线视频 | 偷拍自拍网址 | 国产69精品久久久久999小说 | 一级在线观看 | 欧美日韩后| 亚洲精品网站日本xxxxxxx | 国产精品亚洲视频 | 久久国产精品久久精品国产 | xifan在线a精品一区二区视频网站 | 欧美久久综合性欧美 | 九九视频高清视频免费观看 | 国产精品天天天天影视 | 亚洲欧洲精品一区二区 | 久久第四色 | 亚洲欧美国产高清 | 日韩欧美一区二区三区不卡 | 91tm视频 | 性福利影院 | 天天色影 | 中国一级特黄毛片大片 | 三级做爰大爽视频 | 午夜影院网站 | 亚洲免费视频大全 | 亚洲成人中文字幕 | 免费黄色小视频 | 综合国产| 免费观看一级特黄欧美大片 | 精品久久亚洲 | 色综合久久综合欧美综合 | 青娱乐精品在线 | 婷婷六月综合 | 日韩专区在线观看 | 亚洲国产资源 | 欧美日韩xxx | 日韩欧美一区二区三区在线视频 | 久久综合九色综合欧美狠狠 | 午夜特级毛片 | 97天堂| 精品在线一区二区三区 |