內(nèi)存管理-堆和棧的區(qū)別

堆和棧的區(qū)別
堆與棧是操作系統(tǒng)對進(jìn)程占用的內(nèi)存空間的兩種管理方式哪自,主要有如下幾種區(qū)別:

(1)管理方式不同。棧由操作系統(tǒng)自動分配釋放禁熏,無需我們手動控制壤巷;堆的申請和釋放工作由程序員控制,容易產(chǎn)生內(nèi)存泄漏瞧毙;

(2)空間大小不同胧华。每個進(jìn)程擁有的棧的大小要遠(yuǎn)遠(yuǎn)小于堆的大小。理論上宙彪,程序員可申請的堆大小為虛擬內(nèi)存的大小矩动,進(jìn)程棧的大小 64bits 的 Windows 默認(rèn) 1MB,64bits 的 Linux 默認(rèn) 10MB您访;

(3)生長方向不同铅忿。堆的生長方向向上,內(nèi)存地址由低到高灵汪;棧的生長方向向下檀训,內(nèi)存地址由高到低。

(4)分配方式不同享言。堆都是動態(tài)分配的峻凫,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動態(tài)分配览露。靜態(tài)分配是由操作系統(tǒng)完成的荧琼,比如局部變量的分配。動態(tài)分配由alloca函數(shù)進(jìn)行分配差牛,但是棧的動態(tài)分配和堆是不同的命锄,他的動態(tài)分配是由操作系統(tǒng)進(jìn)行釋放,無需我們手工實現(xiàn)偏化。

(5)分配效率不同脐恩。棧由操作系統(tǒng)自動分配,會在硬件層級對棧提供支持:分配專門的寄存器存放棧的地址侦讨,壓棧出棧都有專門的指令執(zhí)行驶冒,這就決定了棧的效率比較高。堆則是由C/C++提供的庫函數(shù)或運(yùn)算符來完成申請與管理韵卤,實現(xiàn)機(jī)制較為復(fù)雜骗污,頻繁的內(nèi)存申請容易產(chǎn)生內(nèi)存碎片。顯然沈条,堆的效率比棧要低得多需忿。

(6)存放內(nèi)容不同。棧存放的內(nèi)容,函數(shù)返回地址贴谎、相關(guān)參數(shù)汞扎、局部變量和寄存器內(nèi)容等。當(dāng)主函數(shù)調(diào)用另外一個函數(shù)的時候擅这,要對當(dāng)前函數(shù)執(zhí)行斷點(diǎn)進(jìn)行保存澈魄,需要使用棧來實現(xiàn),首先入棧的是主函數(shù)下一條語句的地址仲翎,即擴(kuò)展指針寄存器的內(nèi)容(EIP)痹扇,然后是當(dāng)前棧幀的底部地址,即擴(kuò)展基址指針寄存器內(nèi)容(EBP)溯香,再然后是被調(diào)函數(shù)的實參等鲫构,一般情況下是按照從右向左的順序入棧桥胞,之后是被調(diào)函數(shù)的局部變量省核,注意靜態(tài)變量是存放在數(shù)據(jù)段或者BSS段,是不入棧的尝艘。出棧的順序正好相反湿镀,最終棧頂指向主函數(shù)下一條語句的地址炕吸,主程序又從該地址開始執(zhí)行。堆勉痴,一般情況堆頂使用一個字節(jié)的空間來存放堆的大小赫模,而堆中具體存放內(nèi)容是由程序員來填充的。

從以上可以看到蒸矛,堆和棧相比瀑罗,由于大量malloc()/free()或new/delete的使用,容易造成大量的內(nèi)存碎片雏掠,并且可能引發(fā)用戶態(tài)和核心態(tài)的切換斩祭,效率較低。棧相比于堆乡话,在程序中應(yīng)用較為廣泛摧玫,最常見的是函數(shù)的調(diào)用過程由棧來實現(xiàn),函數(shù)返回地址蚊伞、EBP席赂、實參和局部變量都采用棧的方式存放吮铭。雖然棧有眾多的好處时迫,但是由于和堆相比不是那么靈活,有時候分配大量的內(nèi)存空間谓晌,主要還是用堆掠拳。

無論是堆還是棧,在內(nèi)存使用時都要防止非法越界纸肉,越界導(dǎo)致的非法內(nèi)存訪問可能會摧毀程序的堆溺欧、棧數(shù)據(jù)喊熟,輕則導(dǎo)致程序運(yùn)行處于不確定狀態(tài),獲取不到預(yù)期結(jié)果姐刁,重則導(dǎo)致程序異常崩潰芥牌,這些都是我們編程時與內(nèi)存打交道時應(yīng)該注意的問題。

C語言的內(nèi)存模型分為5個區(qū):棧區(qū)聂使、堆區(qū)壁拉、靜態(tài)區(qū)、常量區(qū)柏靶、代碼區(qū)弃理。每個區(qū)存儲的內(nèi)容如下:

1、棧區(qū):存放函數(shù)的參數(shù)值屎蜓、局部變量等痘昌,由編譯器自動分配和釋放,通常在函數(shù)執(zhí)行完后就釋放了炬转,其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧辆苔。棧內(nèi)存分配運(yùn)算內(nèi)置于CPU的指令集,效率很高返吻,但是分配的內(nèi)存量有限姑子,比如iOS中棧區(qū)的大小是2M。

2测僵、堆區(qū):就是通過new街佑、malloc、realloc分配的內(nèi)存塊捍靠,編譯器不會負(fù)責(zé)它們的釋放工作沐旨,需要用程序區(qū)釋放。分配方式類似于數(shù)據(jù)結(jié)構(gòu)中的鏈表榨婆。

3磁携、靜態(tài)區(qū):全局變量和靜態(tài)變量(在iOS中就是用static修飾的局部變量或者是全局全局變量)的存儲是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域良风,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域谊迄。程序結(jié)束后,由系統(tǒng)釋放烟央。

4统诺、常量區(qū):常量存儲在這里,不允許修改疑俭。

5粮呢、代碼區(qū):存放函數(shù)體的二進(jìn)制代碼。

程序中的內(nèi)存分配
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市啄寡,隨后出現(xiàn)的幾起案子豪硅,更是在濱河造成了極大的恐慌,老刑警劉巖挺物,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件懒浮,死亡現(xiàn)場離奇詭異,居然都是意外死亡识藤,警方通過查閱死者的電腦和手機(jī)嵌溢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹋岩,“玉大人赖草,你說我怎么就攤上這事〖舾觯” “怎么了秧骑?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長扣囊。 經(jīng)常有香客問我乎折,道長,這世上最難降的妖魔是什么侵歇? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任骂澄,我火速辦了婚禮,結(jié)果婚禮上惕虑,老公的妹妹穿的比我還像新娘坟冲。我一直安慰自己,他們只是感情好溃蔫,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布健提。 她就那樣靜靜地躺著,像睡著了一般伟叛。 火紅的嫁衣襯著肌膚如雪私痹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天统刮,我揣著相機(jī)與錄音紊遵,去河邊找鬼。 笑死侥蒙,一個胖子當(dāng)著我的面吹牛暗膜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辉哥,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼桦山,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了醋旦?” 一聲冷哼從身側(cè)響起恒水,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎饲齐,沒想到半個月后钉凌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捂人,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年御雕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滥搭。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡酸纲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瑟匆,到底是詐尸還是另有隱情闽坡,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布愁溜,位于F島的核電站疾嗅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏冕象。R本人自食惡果不足惜代承,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望渐扮。 院中可真熱鬧论悴,春花似錦、人聲如沸墓律。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽只锻。三九已至玖像,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間齐饮,已是汗流浹背捐寥。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祖驱,地道東北人握恳。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像捺僻,于是被迫代替她去往敵國和親乡洼。 傳聞我的和親對象是個殘疾皇子崇裁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 什么行為會增加APP的內(nèi)存占用 創(chuàng)建一個oc對象 定義一個變量 調(diào)用一個函數(shù)或者方法 內(nèi)存管理范圍 任何繼承了NS...
    奔跑吧小螞蟻閱讀 545評論 0 4
  • 為什么管理內(nèi)存: 程序在運(yùn)行的時候,要創(chuàng)建大量的對象束昵,這些對象放在堆和棧上拔稳。(基本類型放在棧上,由系統(tǒng)自動管理锹雏。)...
    我是誰重要嗎閱讀 1,370評論 0 12
  • stack 棧 stack是存在于某作用域(scope)的一塊內(nèi)存空間(memory space)礁遵。例如當(dāng)調(diào)用函數(shù)...
    Angeladoudou閱讀 435評論 0 1
  • 久違的晴天轻绞,家長會。 家長大會開好到教室時佣耐,離放學(xué)已經(jīng)沒多少時間了政勃。班主任說已經(jīng)安排了三個家長分享經(jīng)驗。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,513評論 16 22
  • 創(chuàng)業(yè)是很多人的夢想兼砖,多少人為了理想和不甘選擇了創(chuàng)業(yè)來實現(xiàn)自我價值稼病,我就是其中一個。 創(chuàng)業(yè)后掖鱼,我由女人變成了超人然走,什...
    亦寶寶閱讀 1,802評論 4 1