為什麼棧相對於堆很小?

時間 2021-05-07 02:38:12

1樓:在學習室

很多人的答案喜歡從棧的功能上做解釋,什麼因為棧處理只有push/pop所以小……什麼

棧只是的名詞,我們的關注點是它的功能,棧的功能主要是函式呼叫、區域性變數申請、函式引數傳遞所使用的空間,是為函式呼叫的實現提供一些儲存、恢復操作。

我感覺沒有回答到精髓上。我覺得要從常識邏輯來分析為什麼不推薦把data都放在棧上。其主要原因在我的經驗上來看是棧的LIFO (last in first out)儲存特性導致把data放在棧上會很浪費記憶體空間。

好了,我們來舉個例子,你有三個大檔案,乙個單核CPU,所以你要處理檔案的時候要by一步一步來。 如果我們全部都用棧的話,我們來看一下當前棧的情況:

例圖這個時候你弄完了Data 1, 開始弄Data 2.。。。。

等等!這樣的話 Data 1已經沒用了,存在棧裡面太浪費了。我要把它取出來!

嗯,這就是個問題。棧的規則是LIFO。所以你怎麼取出來呢?

這麼一想,是不是覺得為什麼不推薦存進棧裡面了。

那麼這時候有人可能會問,那我能不能先不全部存進記憶體裡,能不能做完1,取出1,再存2,再做2。

能是能,但是你知道乙個核心,一會兒做I/O, 一會兒ALU做計算,效率不高的……

那麼這個時候又有人問,我是硬體大佬,我改了棧的模式,我可以把Data 1 從中間取出來。這樣行不行?

也行。你改了棧的儲存取出的方法,那麼你還不能只改取出的方案,儲存的方案是不是也要改,你要同意棧不再是堆疊儲存(意思如果你想加Data 4的話,不再只能加在Data 3 下面,看圖)而是同意Data 4可以填補Data 1的空隙來省空間。

那麼恭喜你,這個改進後的「棧」其實就是「堆」的雛形了……

2樓:Sinaean Dean

棧大小自動伸縮我理解沒有問題,可以做到。棧上放很大的東西,要求為棧預留的虛擬位址足夠大,在64位系統中也沒有問題。想來想去,現在似乎沒有問題了,可以這樣做。

還有乙個問題就是棧上記憶體的釋放,必須等棧一點一點pop後才能釋放,也就是說,caller分配的記憶體,callee釋放不了。符合這種使用場景的不多,而且這麼做似乎也沒什麼收益。

3樓:newbie Go

作為乙個外行,我直覺以為,把棧做大沒什麼不可以的,動態增長也沒問題——那實際不又是乙個堆了嗎?

為什麼有些是這麼幹有些不這麼幹呢?

可伸縮性和效能通常成反比,大小和效能通常成反比。

用C的話,寫個簡單的程式對比下,能發現棧和堆上的操作效能差距非常大。似乎是輕鬆十倍以上的差距?不太記得了,反正是非常大

4樓:蘭帕德

核心執行緒結構限制了,你如果問我為啥執行緒記憶體為啥不大點?那就牽扯計算機體系結構了,棧在核心中跟執行緒管理結構,task_struct緊密相連

5樓:tracy要開心

stack大小可設,在create thread的時候呼叫對應的函式就可以了。不過一般不推薦把stack設的很大,除非是可控的recursive的情況。dynamic region是process內所有threads共享的,不用的時候就只是virtual address段而已,在使用的時候按需去申請分配physical frame。

可以直接接在data region的page的後半段,也可以申請新的。個人覺得說它很大,並不太合理。

6樓:原子筆

沒有這個限制喔。很多作業系統都支援程序設定棧大小,什麼rlimit(RLIMIT_AS 之類的。堆可以通過sbrk來調整堆的大小。

linux上面堆和棧中間隔著巨大的空隙給mmap分配。

不過補充一點,棧是線性管理記憶體的而不是像堆那樣可以搞記憶體池來管理記憶體。這也限制了他的使用方法和使用度(棧的釋放必須先申請後釋放,這肯定限制了他的使用場景。)。

7樓:馮東

大塊的記憶體不適合用動態「增長/回退」的方式進行管理。Heap 的動態規劃管理對短生命期的塊會盡量動態重用。長生命期的塊就更不用說了。

Stack 的最頂端一般會留存在 CPU registers 和 cache 中。遇到頻繁但是層次不多的函式呼叫,可以利用高速 cache。大塊的記憶體會破壞這種優化。

不讓用 malloc 的場景,要麼會嚴格限制單個函式記憶體的使用,要麼會事先 statically alloc 大塊記憶體然後自己模擬 malloc 或者用簡單的等大小 block 進行分配。這時候沒有嚴格意義上的 global heap,但是仍然會把大塊記憶體放到 stack 之外。

8樓:shawnhao

一般情況下函式巢狀不了幾層,所以棧的深度不會很大,除了遞迴呼叫。棧裡面的資料也不是一直存在的,如果執行到括號外,棧頂資料就會消失。棧的特殊結構自動做著區域性產量的管理。

然而很多資料的管理要跨不同的資料域,所以有了無視資料域的所謂的堆管理。一開始遠古機器上應該只有「堆」而已,或者壓根就是直接艹記憶體位址。

9樓:惜墨

每個函式都要分配棧

函式執行完就要廢棄,生存期短

不能用作返回值

需要返回的資料就必須放到堆裡,

棧只放一些臨時資料,而且棧不能動態申請記憶體公共資料、動態資料都放堆裡,堆自然就大了

react native為什麼相對於其它跨雙端開發的較成熟?

天國的502 喵喵喵?React Native 成熟?大兄弟,你穿越了麼?React Native從來都跟成熟兩個字沾不上邊。應該說目前的所有跨雙端開發的框架成熟度都不夠。最成熟的應該是H5套殼,但是體驗太差,於是出現了ReactNative和WEEX這些東西,然而後來人們發現使用JS的效能太差,依...

相對於flipflop 為什麼latch更容易產生毛刺(glitch)?

事實上D觸發器是可以用兩個Latch搭建的,所以我覺得不能籠統地講它容易產生glitch。只不過D觸發器通過setup和hold time的規定與設計人員約定好,只要在valid window輸入端穩定,那麼輸出端也就是比較純淨地輸出。輸入端在其它時刻的glitch被侷限在D觸發器內部而不向外傳播,...

華萊士相對於肯德基來說為什麼這麼便宜?

紀念碑 是不是很多人覺得外國的資本家比中國的資本家有良心?幾年前的福喜殭屍肉是不是已經忘了. 某白某白0w0 寫一下我在某十八線小縣城上大學那會吃華萊士的經歷吧 本人主要是麥當勞控,因為小時候就經常去麥當勞的遊樂園 現在好像乙個都看不到了 玩耍和過生日所以非常愛吃麥當勞。雖然被國內資本持股51 以上...