程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 淺談值類型和引用類型在堆和棧中的存儲一

淺談值類型和引用類型在堆和棧中的存儲一

編輯:C#入門知識

首先,讓我們來簡單了解一下什麼是“棧”(stack),什麼是“堆”(heap)。“棧”其實就是一種後入先出(LIFO)的數據結構。在我們.NET Framework裡面,由CLR負責管理,我們程序員不用去擔心垃圾回收的問題;每一個線程都有自己的專屬的“棧”。“堆”的存放就要零散一些,並且由 Garbage Collector(GC)執行管理,我們關注的垃圾回收部分,就是在“堆”上的垃圾回收;其次就是整個進程共用一個“堆”。

 

 

我們先來記住兩條黃金法則:

1.引用類型總是被分配到“堆”上。

2.值類型總是分配到它聲明的地方:

   a.作為引用類型的成員變量分配到“堆”上

   b.作為方法的局部變量時分配到“棧”上

 

要真正理解上面的兩條黃金法則,還需要了解一下,“棧”和“堆”是如何工作的。首先以下面的這個方法為例:

  AddFive(= pValue + 

1.方法AddFive()被壓入“棧”

2.緊接著方法參數pValue被壓入“棧”

3.然後是需要為result變量分配空間,這時被分配到“棧”上。

4.最後返回結果

通過將棧指針指向 AddFive()方法曾使用的可用的內存地址,所有在“棧”上的該方法所使用內存都被清空,且程序將自動回到“棧“上最初的方法調用的位置。

 

 

下面我們來看看,值類型的變量分配到“堆”上到情況。

   MyInt AddFive( result = = pValue + 

和前面一樣,線程開始執行函數,函數參數被壓入線程堆棧。

由於 MyInt 為引用類型,它被分配在“堆”上,並且由一個位於“棧”上的指針引用。

AddFive()函數執行完畢後,“棧”同樣會被清空。

 

最後,只剩下一個 MyInt 類被留在“堆”上(“棧”上再也沒有指向這個 MyInt 類的指針)!這個時候就需要GC機制來處理了。

 

好了,大家對“棧”和“堆”有一定的了解之後,下面讓我們來稍微深入一點,來看兩個例子。

  x =  y == 

返回值大家其實已經知道了吧,還是3。這是為什麼呢?這是因為,值類型,使用的就是值本身,其實在做int y = x的時候,就把3做了一份“拷貝”賦值給了y,然後在y = 4的時候,操作的是這個“拷貝”,並不會操作原來的3。

接下來我們看另外一個例子,MyInt還是使用上面例子中使用過的MyInt類。

 = == 

在這個代碼中,x.MyValue是否還是會是3呢?是否y.MyValue還是操作的3的“拷貝”呢?其實只要運行一下這個代碼,就可以得出結果,x.MyValue還是被修改成了4。這是因為,當我們使用引用類型時,我們實際上是在使用指向這些對象的地址,而不是直接使用這些對象本身。

 

好了,暫時就介紹到這裡,如果有什麼疑問,或者有誤的地方,歡迎大家指點和交流。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved