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