本文主要是討論棧和堆的含義,也就是C#的兩種類據類型:值類型和引用類型; 一、堆與棧 什麼是堆(Heap)? ☞ 堆是無序的,是一片不連續的記憶體域,由用戶自己來控制和釋放,如果用戶自己不釋放的話,當記憶體達到一定的特定值時或程式運行結束時,通過垃圾回收器(GC)來回收。 ☞ 是程式運行期間動態分配的內 ...
本文主要是討論棧和堆的含義,也就是C#的兩種類據類型:值類型和引用類型;
一、堆與棧
- 什麼是堆(Heap)?
☞ 堆是無序的,是一片不連續的記憶體域,由用戶自己來控制和釋放,如果用戶自己不釋放的話,當記憶體達到一定的特定值時或程式運行結束時,通過垃圾回收器(GC)來回收。
☞ 是程式運行期間動態分配的記憶體空間,你可以根據程式的運行情況確定要分配的堆記憶體的大小。
- 什麼是棧(Stack)?
☞ 棧是有順序的,是一片連續的記憶體域,保持著先進後出的原則,由系統自動分配和維護。
☞ 是編譯期間就分配好的記憶體空間,因此代碼中必須就棧的大小有明確的定義。
即, 所分配的記憶體是在一塊連續的記憶體區域內.當我們聲明變數時,那麼編譯器會自動接著當前棧區的結尾來分配記憶體。
二、值類型與引用類型
- 概念:值類型直接存儲其值線上程棧中,引用類型存儲對其值的引用。部署:托管堆上部署了所有引用類型。這裡需要指出一點:如果一個引用類型中的某個屬性是值類型,這個值類型的屬性是分配在托管堆上的。
- 引用類型:基類為Objcet
- 值類型:均隱式派生自System.ValueType;
- 值類型與引用類型表:
- 記憶體分配
☞ 值類型變數聲明後,無論是否已經賦值,編譯器都會為其分配記憶體。
☞ 引用類型當聲明一個類時,只會在棧中分配一小塊記憶體用於存放引用地址,此時並沒有為其分配堆上的空間。當類實例化時,分配記憶體空間,並把堆上空間的地址保存到棧上分配的小塊空間中。
☞ 值類型的實例通常是線上程棧上分配的(靜態分配),但是在某些情形下可以存儲在堆中。
☞ 引用類型的對象總是在進程堆中分配(動態分配)。
- 示例代碼
運行結果
從圖中我們可以看出,兩個引用類型sc1,sc2都指向同一個托管堆上的空間,所以最後一個指向的會覆蓋掉前面的。
而結構是值類型,雖然使用sv2=sv1,把sv1對象賦值給sv2,但是它會線上程棧中分配一個獨立的空間,當修改某一個對象的值的時候,不會影響到另一個對象
所以,值類型和引用類型的區別就是:
1、它們存儲的位置不一樣
2、如果是引用類型,當兩個對象指向同一個地方,修改某一個的時候,其它對象的值會發生改變
內容參考來自文章:
作者:遙遠的Ta