對於棧記憶體和堆記憶體的理解

2021-10-08 13:46:01 字數 1263 閱讀 5424

1.和堆一樣儲存在計算機ram中

2.棧是為執行執行緒留出的記憶體空間

3.棧附屬於執行緒,因此當執行緒結束時棧被**

4.執行緒被建立的時候,設定棧的大小

5.當用棧過多時會導致棧溢位(無窮次/大量的遞迴呼叫,或者大量的記憶體分配)

6.如果在編譯之前精確的知道要分配資料的大小並且不是太大的時候,可以使用棧

棧底層1.棧經常與sp暫存器一起工作,最初sp指向棧頂

2.cpu用push指令將資料壓棧,用pop指令來彈棧。壓棧時sp值減少,彈棧時sp值增大,訪問和獲取資料都是cpu暫存器的值

3.當函式被呼叫時,cpu使用特定的指令把當前的ip(存放偏移位址的乙個暫存器)壓棧,即執行**的位址,cpu接下來將呼叫函式位址賦給ip,進行呼叫,當函式返回時,舊的ip被彈棧,cpu繼續執行函式呼叫之前的**。

4.當進入函式時,sp向下擴充套件,擴充套件到確保為函式的區域性變數留存足夠大小的空間。當函式返回時,sp通過返回原來的位置來釋放空間。

5.如果函式有引數的話,在函式呼叫之前,會將引數壓棧,函式中的**通過sp的當前位置來定位引數並訪問他們。

6.棧要受到記憶體塊的限制,不斷的函式巢狀/為區域性變數分配太多的空間,可能會導致棧溢位。當棧中的記憶體區域都已經被使用完之後繼續向下寫(低位址),會觸發乙個cpu異常。

1.和棧一樣儲存在計算機ram中

2.堆是為動態分配預留的記憶體空間

3.堆通常通過執行時在應用程式啟動時被分配,當應用程式(程序)退出時被**

4.在應用程式啟動的時候,設定堆的大小,但是可以在需要的時候進行擴充套件

5.如果申請的緩衝區過大的話,可能申請失敗

6.在執行期間不知道會需要多大的資料或者需要分配大量的記憶體的時候,建議使用堆

堆底層1.堆包含乙個鍊錶來維護已用和空閒的記憶體塊。在堆上新分配記憶體是從空閒的記憶體塊中找到一些滿足要求的合適塊,這個操作會更新堆中的塊鍊錶。

2.堆增加新塊通常從低位址向高位址擴充套件。因此可以認為堆隨著記憶體分配而不斷的增加大小。

3.申請和釋放許多小的塊可能會產生如下狀態:在已用塊之間存在很多小的空閒塊,進而申請大塊記憶體失敗,雖然空閒塊的總和足夠,但是空閒的小塊是零散的,不能滿足申請的大小,也就是堆碎片。

4.當旁邊有空閒塊的已用塊被釋放時,新的空閒塊可能會與相鄰的空閒塊合併為乙個大的空閒塊,這樣可以有效的減少堆碎片的產生。

每乙個執行緒都有乙個棧,但是每乙個應用程式通常都只有乙個堆(為不同型別分配記憶體使用多個堆的情況也是有的)。 棧比堆要快,因為它的訪問模式使它可以輕鬆的分配和重新分配記憶體(指標/整型只是進行簡單的遞增或者遞減運算),所有的空閒記憶體都是連續的。

堆記憶體與棧記憶體的理解

記憶體中的堆與棧的根本區別在於堆記憶體由使用者自己申請,需要自己去釋放,否則會造成記憶體洩露,最終記憶體空間不夠。而棧記憶體則是由系統區釋放,程式設計師不需要自己去釋放。棧記憶體用來存放臨時申明的變數,如乙個函式中的區域性變數等。拿乙個函式為例,函式有返回值,函式引數 入參,出參 區域性變數,返回值...

堆記憶體和棧記憶體

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

堆記憶體和棧記憶體

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