堆、棧以及靜態區域的區別

一、內存基本構成
可編程內存在基本上分為這樣的幾大部分:靜態存儲區、堆區和棧區。他們的功能不同,對他們使用方式也就不同。

  • 堆區:亦稱動態內存分配。程序在運行的時候用mallocnew申請任意大小的內存,程序員自己負責在適當的時候用freedelete釋放內存。動態內存的生存期可以由我們決定,如果某動態內存不再使用,需要將其釋放掉,否則就會發生內存泄漏現象。
    (OC中對象存儲于堆中,當對象的應用計數為0時自動釋放該對象)

  • 棧區:在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置于處理器的指令集中,效率很高,但是分配的內存容量有限。
    (OC中 非對象變量 都存在棧中)

  • 靜態存儲區:內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。它主要存放靜態數據全局數據常量

二、使用時需注意的規則

  • 【規則1】用malloc 或new 申請內存之后,應該立即檢查指針值是否為NULL。防止使用指針值為NULL的內存。
  • 【規則2】不要忘記為數組動態內存賦初值。防止將未被初始化的內存作為右值使用。
  • 【規則3】避免數組指針的下標越界,特別要當心發生“多1”或者“少1”操作。
  • 【規則4】動態內存的申請與釋放必須配對,防止內存泄漏
  • 【規則5】用free 或delete 釋放了內存之后,立即將指針設置為NULL,防止產生野指針

三、堆與棧的討論

1、管理方式:
  • 堆中資源由程序員控制(容易產生memory leak),
  • 棧中資源由編譯器自動管理,無需手工控制。
2、系統響應:
  • 對于堆,應知道系統有一個記錄空閑內存地址的鏈表,當系統收到程序申請時,遍歷該鏈表,尋找第一個空間大于申請空間的堆結點,刪除空閑結點鏈表中的該結點,并將該結點空間分配給程序(大多數系統會在這塊內存空間首地址記錄本次分配的大小,這樣delete才能正確釋放本內存空間,另外系統會將多余的部分重新放入空閑鏈表中)。
  • 對于棧,只要棧的剩余空間大于所申請空間,系統為程序提供內存,否則報異常提示棧溢出。
3、空間大小:
  • 堆是不連續的內存區域(因為系統是用鏈表來存儲空閑內存地址),堆大小受限于計算機系統中有效虛擬內存(32bit系統理論上是4G),所以堆的空間比較靈活,比較大。
  • 棧是一塊連續的內存區域,大小是操作系統預定好的,windows下棧大小是2M(也有是1M,在編譯時確定,VC中可設置)。
4、碎片問題:
  • 對于堆,頻繁的new/delete會造成大量碎片,使程序效率降低。
  • 對于棧,它是一個先進后出的隊列,進出一一對應,不會產生碎片。
5、生長方向:
  • 堆向上,向高地址方向增長。
  • 棧向下,向低地址方向增長。
6、分配方式:
  • 堆都是動態分配(沒有靜態分配的堆)。
  • 棧有靜態分配動態分配
    靜態分配由編譯器完成(如局部變量分配),
    動態分配由alloca函數分配,但棧的動態分配的資源由編譯器進行釋放,無需程序員實現。
7、分配效率:
  • 堆由C/C++函數庫提供,機制很復雜。所以堆的效率比棧很多。
  • 棧是基于系統提供的數據結構,計算機在底層對棧提供支持,分配專門寄存器存放棧地址,棧操作有專門指令

四、為什么要把堆和棧區分出來

1、從軟件設計的角度看,棧代表了處理邏輯,而堆代表了數據。這種隔離、模塊化的思想,使得處理邏輯更為清晰
2、使得中的內容可以被多個棧共享(也可以理解為多個線程訪問同一個對象
  • 一方面這種共享提供了一種有效的數據交互方式(如:共享內存)
  • 另一方面,堆中的共享常量和緩存可以被所有棧訪問,節省了空間
3、使得動態增長成為可能,相應棧中只需記錄堆中的一個地址即可

棧因為運行時的需要,比如保存系統運行的上下文,需要進行地址段的劃分。由于棧只能向上增長,因此就會限制住棧存儲內容的能力。而堆不同,堆中的對象是可以根據需要動態增長的

4、面向對象就是堆和棧的完美結合。

對象的屬性其實就是數據,存放在中;而對象的行為(方法),就是運行邏輯,放在中。我們在編寫對象的時候,其實即編寫了數據結構,也編寫的處理數據的邏輯

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容

  • 在函數中定義的一些基本類型的變量和對象的引用變量都在函數的棧內存中分配。 當在一段代碼塊定義一個變量時,Java就...
    木有魚丸啦閱讀 562評論 0 0
  • 喜歡的話記得點贊 一、內存管理:移動設備的內存及其有限,每一個APP所能占用的內存是有限制的二、什么行為會增加AP...
    茉上心弦閱讀 2,024評論 1 12
  • 1. 基礎知識 1.1、 基本概念、 功能 馮諾伊曼體系結構1、計算機處理的數據和指令一律用二進制數表示2、順序執...
    yunpiao閱讀 5,381評論 1 22
  • 365期感謝二組學員 【日精進打卡第32天】 【知~學習】 1、讀《六項精進》大...
    大臉貓wjyxd閱讀 279評論 0 0
  • 二.水 除卻了山,便要言及了水。 我的家鄉實在是個好地方,有山有水,山水如畫。如畫的山水里,孕育了一群平山填水的好...
    雷芒閱讀 577評論 0 0