爲什麼會有堆內存和棧內存?

前戲

在之前的調研中瞭解到,有些童鞋想要我講解下“棧”和“堆”。其實這兩種內存方式,真的沒有什麼好講的,反而覺得可以深挖下,這就是文章題目的來源。“知其然”,首先要“知其所以然”。

問C/C++為什麼要堆棧?

回答這個問題之前就要問以前寫彙編的為什麼寫著寫著就喜歡把內存分兩塊來用?

至於這個問題你跑去C/C++論壇和彙編論壇,估計都沒幾個人能讓你信服地說清楚原因,我不是彙編程序員,所以只簡單說說我的看法。

首先彙編裡,變量的概念幾乎沒有了,有的只是各種內存地址,不管是實地址還是虛地址,你訪問一個變量就是靠地址,所以如果你不記住一個變量的地址,你就沒辦法去操作它,這就產生了問題,如果你的程序要1000個變量,你就把他們的地址全記下來嗎?

這顯然是不現實的,首先這會浪費很多空間,因為幾乎任何操作都離不開操作變量,也就是地址,那麼就相當於你要用兩倍甚至更多的空間來表示你的程序,而一半浪費在地址上,其次這樣寫程序也是沒有效率的,1000個變量,難道你能把他們的地址全背下來嗎?或者說當你看到地址0x1234的值賦值給地址0x2345時,你如何記得起0x1234和0x2345是兩個幹什麼用的變量?

所以以一種系統的方法管理內存就顯得尤為重要,畢竟我們要用計算機來方便自己,而不是拿來自虐。經過很多人的摸索,人們發現變量主要是兩種形式,一種內容短小(比如一個int整數),需要頻繁訪問,但是生命週期很短,通常只在一個功能內存在,而另一種內容可能很多(比如很長一個字符串),可能不需要太頻繁的訪問,但生命週期較長,通常很多個功能中可能都要用到,那麼自然將這兩類變量分開就顯得比較理性。

一類存儲在棧區,通常是局部變量、操作符棧、函數參數傳遞和返回值,另一類存儲在堆區,通常是較大的結構體(或者OOP中的對象)、需要反覆訪問的全局變量。

堆區就是各種慢,申請內存慢,訪問慢,修改慢,釋放慢,整理慢(或者說GC垃圾回收),但優點也不言而喻,訪問隨機靈活,空間超大,在不超可用內存的情況下你要多大就給多大。

棧區就像臨時工,幹完就跑,所以超快,但是缺點也很多,比如生命週期短,一般只能在一個功能內存活,又比如你需要事先知道需要多大的棧(事實上絕大多數語言棧區要分配的大小編譯期就確定了),而且通常最大棧區可用內存都很小,你不可能往棧區裡堆很多數據。

結語

用這篇文章我想告訴大家,每件事情都有其存在的道理。在技術上也是一樣的。希望各位都能“知其所以然”,以後我的文章中,也會往這個方向寫,感謝各位支持!

在本頭條號的主頁置頂文章中有【文章分類】包含:

[數據庫系列]

[數據結構和算法系列]

[高級網絡編程篇系列]

[Linux系統篇系列]

[C++進階篇系列]

[C++基礎知識篇系列]

[協議篇系列]

[設計模式系列]

不要只收藏和轉發哦,點擊屏幕右上角的【關注】每天文章不落下。


分享到:


相關文章: