C 深入理解堆和棧的區別

2021-10-10 08:40:28 字數 1596 閱讀 5015

在講棧和堆之前,我們先看看值型別和引用型別:

類別描述

值型別基本資料型別 列舉型別 結構型別

引用型別

類 介面 陣列

1)值型別:值型別總是分配在它宣告的地方,作為區域性變數時,儲存在棧上;作為類物件的字段時,則跟隨此物件儲存在堆中。

class

program

}public

class

person

//值型別

}

&b

0x001af368

*&b: 0xff

&c0x001af364

*&c: 0xffff

&person

0x001af360

*&person: 0x02562390

&a0x001af35c

*&a: 0x0000000a

我們發現了幾條規律:

1)先宣告的變數在棧中的位址比較大,後宣告的變數在棧中的位址比較小

2)在棧中,對於值型別來說,那塊位址儲存的就是變數的值;而對於引用型別來說,儲存的是對堆的引用(在堆中的位址)

棧位址是從高往低分配的,按照先後定義的順序依次壓入棧中,相鄰變數的位址之間不會存在其他變數。

棧是有作業系統自動分配釋放的(作為程式設計師,你不需要顯示對它做任何事),用於儲存變數的值、程式執行的當前環境、方法的引數和型別的引用等。

堆裡的記憶體能夠任意順序的存入和移除,位址一般是從低往高分配。

堆裡的資料由clr的自動gc在判斷出程式的**將不會再訪問某項資料項時,自動清除無主的堆物件。

在程式執行的時候,每乙個執行緒都會維護乙個自己的專屬執行緒堆疊(就是我們說的棧)。當乙個方法被呼叫的時候,主線程開始在所屬程式集的元資料中,查詢被呼叫方法,然後通過jit即時編譯並把結果(一般是本地cpu指令)放在棧頂,cpu通過匯流排從棧頂取指令,驅動程式以執行下去。

棧通常儲存著我們**執行的步驟,而堆上存放的則多是物件、資料等。在呼叫方法的時候,記憶體從棧的頂部開始分配,儲存和方法關聯的一些資料項,這塊記憶體叫做方法的棧幀(stack frame)。棧幀包含的記憶體儲存如下內容:

1)返回位址,也就是在方法退出的時候繼續執行的位置。

2)這些引數分配的記憶體,也就是方法的值引數,或者還可能時引數陣列。

3)各種和方法呼叫相關的其他管理資料項。

在方法呼叫時,整個棧幀都會壓入棧;在方法推出的時候,整個棧幀都會從棧頂彈出,彈出棧幀有的時候也叫做棧展開。

棧記憶體無需我們管理,也不受gc管理。當棧頂元素使用完畢,立馬釋放。而堆則需要gc清理,它像乙個倉庫,儲存著我們使用的各種物件資訊,跟棧不同的是他們被呼叫完畢不會立即被清理掉。

深入理解堆和棧的區別

一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其 操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os回 收 注意它...

深入理解堆和棧(選)

堆和棧的區別 一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os ...

堆和棧的深入詳細理解

一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其 操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os回 收 注意它...