深入理解C#中的堆(Heap)與棧(Stack),一次性全都掌握!

前言:今天我們着重講解.Net下的棧(Stack)和託管堆(Heap)(簡稱堆)。如果你想提高程序性能,理解棧和堆,那學習這塊更是必須的!

一、C#中的值類型和引用類型

在講堆與棧之前,我們先看看值類型和引用類型,這樣更能幫助我們理解堆與棧。

在這裏插入圖片描述

通過上面這個表格,我們可以看到,類型被分爲兩種:值類型(基本數據類型、枚舉類型、結構類型)和引用類型(類、接口、數組)。

下來,我們進行簡單理解:

  1. 值類型只需要一段單獨的內存,用於存儲實際的數據(單獨定義的時候放在棧中)。
  2. 引用類型需要兩段內存。
  1. 第一段存儲實際的數據,它總是位於堆中。
  2. 第二段是一個引用,指向數據在堆中的存放位置。

在這裏插入圖片描述

1、值類型與引用類型的存儲方式

  • 值類型:值類型總是分配在它聲明的地方,做爲局部變量時,存儲在棧上;類對象的字段時,則跟隨此類存儲在堆中。
  • 引用類型:引用類型存儲在堆中。類型實例化的時候,會在堆中開闢一部分空間存儲類的實例。類對象的引用還是存儲在棧中。

2、通過一個案例理解一下

// 值類型,保存在棧中
int num = 100;
// 引用類型,保存在堆中
int[] nums = {1,2,3,4,5};
// 接下來,我們輸出一下
Console.WriteLine(num);
Console.WriteLine(nums);

在這裏插入圖片描述
通過上面這個例子,我們可以看到,num爲值類型,所以它直接輸出了值,而我們的nums爲引用類型,它無法直接輸出值,而是輸出了一個引用。

3、值類型與引用類型的區別

  1. 值類型與引用類型都繼承自Systerm.Object類。不同之處,幾乎所有的引用類型都是直接從Systerm.Object繼承,而值類型則是繼承Systerm.Object的子類Systerm.ValueType類。
  2. 我們在給引用類型的變量賦值的時候,其實只是賦值了對象的引用;而給值類型變量賦值的時候是創建了一個副本(說通俗點,就是克隆了一個變量)。

二、堆與棧簡單理解

C#程序在CLR上運行的時候,內存從邏輯上劃分兩大塊:棧,堆。這倆基本元素組成我們C#程序的運行環境。

1、堆與棧概念介紹

堆:在c裏面叫堆,在c#裏面其實叫託管堆。

棧:就是堆棧,因爲和堆一起叫着彆扭,就簡稱爲棧。

2、託管堆

託管堆不同於堆,它是由CLR(公共語言運行庫(Common Language Runtime))管理,當堆中滿了之後,會自動清理堆中的垃圾。所以,做爲.net開發,我們不需要關心內存釋放的問題。

3、內存堆棧與數據堆棧

  1. 內存堆棧:存在內存中的兩個存儲區(堆區,棧區)。
  1. 棧區:存放函數的參數、局部變量、返回數據等值,由編譯器自動釋放。
  2. 堆區:存放着引用類型的對象,由CLR釋放。
  1. 數據堆棧:是一種後進先出的數據結構,它是一個概念,主要是棧區。

三、堆與棧區別分析

棧通常保存着我們代碼執行的步驟,如一個值類型的變量的初始化或者一個方法的聲明。而堆上存放的則多是對象,數據等。我們可以把棧想象成一個接着一個疊放在一起的盒子。當我們使用的時候,每次從最頂部取走一個盒子。同樣,我們的棧也是如此,當一個方法(或類型)被調用完成的時候,就從棧頂取走,接着下一個,這也就是我們常說的 “先進後出” 。堆則不然,像是一個倉庫,儲存着我們使用的各種對象等信息,當我們需要調用的時候,會去裏面自行尋找並調用。跟棧不同的是它們被調用完畢不會立即被清理掉。

注意:棧內存無需我們管理,也不受GC管理。當棧頂元素使用完畢,立馬釋放。而堆則需要GC(Garbage Collection:垃圾收集器)清理。

四、堆與棧存儲講解

我們把內存分爲堆空間和棧空間,區別如下:

  1. 棧空間比較小,但是讀取速度快。
  2. 堆空間比較大,但是讀取速度慢。

1、棧的深入講解

棧(Stack)最明顯的特徵就是“先進後出”,本質上講堆棧也是一種線性結構,符合線性結構的基本特點:即每個節點有且只有一個前驅節點和一個後續節點。棧把所有操作限制在"只能在線性結構的某一端"進行,而不能在中間插入或刪除元素。我們把數據放入棧頂稱爲入棧(push), 從棧頂刪除數據稱爲出棧(pop)。
在這裏插入圖片描述

2、堆的深入講解

堆(Heap)是一塊內存區域,與棧不同,堆裏的內存能夠以任意順序存入和移除。
在這裏插入圖片描述

五、GC(Garbage Collection)垃圾收集器介紹

CLR的GC就是內存管理機制,我們寫程序不需要關心內存的使用,因爲這些都是CLR幫我們做了。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章