什麼是堆和棧,它們在哪兒?

2021-08-19 05:42:10 字數 1706 閱讀 3411

問題描述

程式語言書籍中經常解釋值型別被建立在棧上,引用型別被建立在堆上,但是並沒有本質上解釋這堆和棧是什麼。我僅有高階語言程式設計經驗,沒有看過對此更清晰的解釋。我的意思是我理解什麼是棧,但是它們到底是什麼,在哪兒呢(站在實際的計算機物理記憶體的角度上看)?

在通常情況下由作業系統(os)和語言的執行時(runtime)控制嗎?

它們的作用範圍是什麼?

它們的大小由什麼決定?

哪個更快?

答案一

棧是為執行執行緒留出的記憶體空間。當函式被呼叫的時候,棧頂為區域性變數和一些 bookkeeping 資料預留塊。當函式執行完畢,塊就沒有用了,可能在下次的函式呼叫的時候再被使用。棧通常用後進先出(lifo)的方式預留空間;因此最近的保留塊(reserved block)通常最先被釋放。這麼做可以使跟蹤堆疊變的簡單;從棧中釋放塊(free block)只不過是指標的偏移而已。

堆(heap)是為動態分配預留的記憶體空間。和棧不一樣,從堆上分配和重新分配塊沒有固定模式;你可以在任何時候分配和釋放它。這樣使得跟蹤哪部分堆已經被分配和被釋放變的異常複雜;有許多定製的堆分配策略用來為不同的使用模式下調整堆的效能。

每乙個執行緒都有乙個棧,但是每乙個應用程式通常都只有乙個堆(儘管為不同型別分配記憶體使用多個堆的情況也是有的)。

直接回答你的問題: 1. 當執行緒建立的時候,作業系統(os)為每乙個系統級(system-level)的執行緒分配棧。通常情況下,作業系統通過呼叫語言的執行時(runtime)去為應用程式分配堆。 2. 棧附屬於執行緒,因此當執行緒結束時棧被**。堆通常通過執行時在應用程式啟動時被分配,當應用程式(程序)退出時被**。 3.當執行緒被建立的時候,設定棧的大小。在應用程式啟動的時候,設定堆的大小,但是可以在需要的時候擴充套件(分配器向作業系統申請更多的記憶體)。 4.棧比堆要快,因為它訪問模式使它可以輕鬆的分配和重新分配記憶體(指標/整型只是進行簡單的遞增或者遞減運算),然而堆在分配和釋放的時候有更多的複雜的 bookkeeping 參與。另外,在棧上的每個位元組頻繁的被復用也就意味著它可能對映到處理器快取中,所以很快(譯者注:區域性性原理)。

答案二

stack:

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

在棧上建立變數的時候會擴充套件,並且會自動**。

相比堆而言在棧上分配要快的多。

用資料結構中的棧實現。

儲存區域性資料,返回位址,用做引數傳遞。

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

在棧上的資料可以直接訪問(不是非要使用指標訪問)。

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

當你程式啟動時決定棧的容量上限。

heap:

和棧一樣儲存在計算機ram。

在堆上的變數必須要手動釋放,不存在作用域的問題。資料可用 delete, delete 或者 free 來釋放。

相比在棧上分配記憶體要慢。

通過程式按需分配。

大量的分配和釋放可造成記憶體碎片。

在 c++ 中,在堆上建立數的據使用指標訪問,用 new 或者 malloc 分配記憶體。

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

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

可能造成記憶體洩露。

原文:

我們和牛人的差距在哪兒,細節問題?

記得剛實習的時候,整個專案組開過一次會,了一下專案的進展情況和遇到的一些問題,當時專案組人基本都到齊了,包括分管副總,專案總監,開發經理等所有的管理人員以及所有參與開發的人員。由於當時專案可算是陷入了乙個僵局,原計畫的上線時間不可避免的遭到了推遲,只是在某個省進行了一次試執行,試執行結束後,領導開會...

什麼是堆和棧

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

什麼是堆和棧

堆 管資料儲存的。引用資料型別的存放,所以堆的空間是比較大的 每個執行緒都有自己的棧,棧中的資料都是以棧幀 stack frame 的格式為基本單位進行儲存的。棧中儲存的就是乙個個棧幀 在這個執行緒上正在執行的每個方法都各自對應乙個棧幀。方法和棧幀一一對應,乙個方法的執行會伴隨這棧幀入棧,乙個方法的...