對象內存模型


C#的對象內存模型
寫這篇博客的主要目的是為了加深自己的理解,如有不對的地方,請各位見諒。

 

C#的對象內存模型:

一、棧內存和堆內存
1、棧內存

  由編譯器自動分配和釋放,主要用來保存一些局部變量、函數的參數等,例如,int a = 10 ,那么編譯器會自動在棧上開辟一塊內容用來存儲變量a。
2、堆內存

  由程序員手動申請和釋放,在C++中,通過new關鍵字申請,編譯器不會釋放,必須通過delete釋放,對於C#,通過new 關鍵字申請,因為編譯器的垃圾回收機制,程序員不需要手動釋放內存。例如,我們為類student聲明了一個對象zhangsan,student zhangsan = new student(),首先,編譯器會分配一塊棧上的內存存儲變量zhangsan,然后在堆上開辟一塊內存來存儲student對象,最后把堆上的地址存儲到變量zhangsan中,如果我們又創建了一個對象lisi,student lisi= new student(),然后lisi = zhangsan,其實更改的只是存儲在棧上的lisi的值,即所指向的對象在堆上的地址,如下圖所示:

                 

 

3、棧內存和堆內存的比較

  內存分配

  棧:后進先出式,由編譯器自動分配相應類型的大小,分配的大小受限於棧的大小;

  堆:隨意分配,由程序員手動申請指定大小,分配的大小受限於虛擬內存。

  效率

  棧:高

  堆:相對棧低

二、值類型和引用類型

  1、值類型

  值類型變量存儲的是變量的值,直接存儲在棧內存中;

  2、引用類型

  引用類型變量存儲的是變量所在的內存的地址,引用類型變量的實際數據存儲在堆內存中,變量本身存儲在棧內存中,存儲的是指向堆的地址,通常是四個字節,保存着一個地址數值。

  C#中的值類型:struct,enum(對於int,float類型,都屬於struct類型)

    引用類型:class,delegate,array,interface

  具體如下圖所示:

                                 

三、深拷貝和淺拷貝

  我們在編程中常常會遇到這種問題,我們已經有了一個對象a,並且對象a已經有了一些具體的值,現在我們想創建一個a的副本即對象b,我們希望,操作對象b的同時不改變對象a的值,也就是說對象a和對象b是兩個完全獨立的對象,這即是深拷貝。深拷貝的概念:源對象與拷貝對象互相獨立,其中任何一個對象的改動都不會對另外一個對象造成影響。

  當兩個對象指向同一個地址時,如果我們改變其中一個對象的值,另一個對象也被相應的改變,這即是淺拷貝。淺拷貝的概念:淺拷貝時兩個對象並未完全“分離”,改變頂級對象的內容,不會對另一個對象產生影響,但改變子對象的內容,則兩個對象同時被改變。

  這種差異的產生,即是取決於拷貝子對象時復制內存還是復制指針。深拷貝為子對象重新分配了一段內存空間,並復制其中的內容;淺拷貝僅僅將指針指向原來的子對象。

  一些需要注意的東西

  (1):String字符串對象是引用對象,但是很特殊,它表現的如值對象一樣,即對它進行賦值,分割,合並,並不是對原有的字符串進行操作,而是返回一個新的字符串對象

  (2):Array數組對象是引用對象,在進行賦值的時候,實際上返回的是源對象的另一份引用而已;因此如果要對數組對象進行真正的復制(深拷貝),那么需要新建一份數組對象,然后將源數組的值逐一拷貝到目的對象中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM