C# 堆棧與堆(託管堆)

來源:互聯網
上載者:User

首先堆棧和堆(託管堆)都在進程的虛擬記憶體中。(在32位處理器上每個進程的虛擬記憶體為4GB)

堆棧stack

堆棧中儲存實值型別。

堆棧實際上是向下填充,即由高記憶體位址指向地記憶體位址填充。

堆棧的工作方式是先分配記憶體的變數後釋放(先進後出原則)。

堆棧中的變數是從下向上釋放,這樣就保證了堆棧中先進後出的規則不與變數的生命週期起衝突!

堆棧的效能非常高,但是對於所有的變數來說還不太靈活,而且變數的生命週期必須嵌套。

通常我們希望使用一種方法分配記憶體來儲存資料,並且方法退出後很長一段時間內資料仍然可以使用。此時就要用到堆(託管堆)!

 

 堆(託管堆)heap

堆(託管堆)儲存參考型別。

此堆非彼堆,.NET中的堆由垃圾收集器自動管理。

與堆棧不同,堆是從下往上分配,所以自由的空間都在已用空間的上面。

比如建立一個對象:

Customer cus;

cus = new Customer();

申明一個Customer的引用cus,在堆棧上給這個引用分配儲存空間。這僅僅只是一個引用,不是實際的Customer對象!

cus佔4個位元組的空間,包含了儲存Customer的引用地址。

接著分配堆上的記憶體以儲存Customer對象的執行個體,假定Customer對象的執行個體是32位元組,為了在堆上找到一個儲存Customer對象的儲存位置。

.NET運行庫在堆中搜尋第一個從未使用的,32位元組的連續Block StorageCustomer對象的執行個體!

然後把分配給Customer對象執行個體的地址賦給cus變數!

 

從這個例子中可以看出,建立對象引用的過程比建立值變數的過程複雜,且不能避免效能的降低!

實際上就是.NET運行庫儲存對的狀態資訊,在堆中添加新資料時,堆棧中的引用變數也要更新。效能上損失很多!

有種機制在分配變數記憶體的時候,不會受到堆棧的限制:把一個引用變數的值賦給一個相同類型的變數,那麼這兩個變數就引用同一個堆中的對象。

當一個應用變數出範圍時,它會從堆棧中刪除。但引用對象的資料仍然保留在堆中,一直到程式結束 或者 該資料不被任何變數應用時,垃圾收集器會刪除它。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.