操作系統(tǒng)iOS中應(yīng)用程序使用的計(jì)算機(jī)內(nèi)存不是統(tǒng)一分配空間,運(yùn)行代碼使用的空間在三個(gè)不同的內(nèi)存區(qū)域,分成三個(gè)段:“text segment“赁咙,“stack segment”凤覆,“heap segment”。
段“text segment”是應(yīng)用程序運(yùn)行時(shí)應(yīng)用程序代碼存在的內(nèi)存段。每一個(gè)指令撮奏,每一個(gè)單個(gè)函數(shù)梯浪、過(guò)程荠藤、方法和執(zhí)行代碼都存在這個(gè)內(nèi)存段中直到應(yīng)用程序退出摊趾。一般情況下,你不會(huì)真的不得不知道這個(gè)段的任何事情秕重。
當(dāng)應(yīng)用開(kāi)始以后留荔,函數(shù)main()被調(diào)用验靡,一些空間分配在”stack”中。這是為應(yīng)用分配的另一個(gè)段的內(nèi)存空間岛杀,這是為了函數(shù)變量存儲(chǔ)需要而分配的內(nèi)存裳瘪。每一次在應(yīng)用中調(diào)用一個(gè)函數(shù)还最,“stack”的一部分會(huì)被分配在”stack”中拓轻,稱之為”frame”。新函數(shù)的本地變量分配在這里。
正如名稱所示酪劫,“stack”是后進(jìn)先出(LIFO)結(jié)構(gòu)透敌。當(dāng)函數(shù)調(diào)用其他的函數(shù)時(shí)划滋,“stack frame”會(huì)被創(chuàng)建处坪;當(dāng)其他函數(shù)退出后,這個(gè)“frame”會(huì)自動(dòng)被破壞架专。
“heap”段也稱為”data”段同窘,提供一個(gè)保存中介貫穿函數(shù)的執(zhí)行過(guò)程,全局和靜態(tài)變量保存在“heap”中部脚,直到應(yīng)用退出想邦。
為了訪問(wèn)你創(chuàng)建在heap中的數(shù)據(jù),你最少要求有一個(gè)保存在stack中的指針委刘,因?yàn)槟愕腃PU通過(guò)stack中的指針訪問(wèn)heap中的數(shù)據(jù)案狠。
你可以認(rèn)為stack中的一個(gè)指針僅僅是一個(gè)整型變量,保存了heap中特定內(nèi)存地址的數(shù)據(jù)钱雷。實(shí)際上,它有一點(diǎn)點(diǎn)復(fù)雜吹零,但這是它的基本結(jié)構(gòu)罩抗。
簡(jiǎn)而言之,操作系統(tǒng)使用stack段中的指針值訪問(wèn)heap段中的對(duì)象灿椅。如果stack對(duì)象的指針沒(méi)有了套蒂,則heap中的對(duì)象就不能訪問(wèn)钞支。這也是內(nèi)存泄露的原因。
在iOS操作系統(tǒng)的stack段和heap段中操刀,你都可以創(chuàng)建數(shù)據(jù)對(duì)象烁挟。
stack對(duì)象的優(yōu)點(diǎn)主要有兩點(diǎn),一是創(chuàng)建速度快骨坑,二是管理簡(jiǎn)單撼嗓,它有嚴(yán)格的生命周期。stack對(duì)象的缺點(diǎn)是它不靈活欢唾。創(chuàng)建時(shí)長(zhǎng)度是多大就一直是多大且警,創(chuàng)建時(shí)是哪個(gè)函數(shù)創(chuàng)建的,它的owner就一直是它礁遣。不像heap對(duì)象那樣有多個(gè)owner斑芜,其實(shí)多個(gè)owner等同于引用計(jì)數(shù)。只有heap對(duì)象才是采用“引用計(jì)數(shù)”方法管理它祟霍。
stack對(duì)象的創(chuàng)建
只要棧的剩余空間大于stack對(duì)象申請(qǐng)創(chuàng)建的空間杏头,操作系統(tǒng)就會(huì)為程序提供這段內(nèi)存空間,否則將報(bào)異常提示棧溢出沸呐。
heap對(duì)象的創(chuàng)建
操作系統(tǒng)對(duì)于內(nèi)存heap段是采用鏈表進(jìn)行管理的醇王。操作系統(tǒng)有一個(gè)記錄空閑內(nèi)存地址的鏈表,當(dāng)收到程序的申請(qǐng)時(shí)垂谢,會(huì)遍歷鏈表厦画,尋找第一個(gè)空間大于所申請(qǐng)的heap節(jié)點(diǎn),然后將該節(jié)點(diǎn)從空閑節(jié)點(diǎn)鏈表中刪除滥朱,并將該節(jié)點(diǎn)的空間分配給程序根暑。
例如:
NSString的對(duì)象就是stack中的對(duì)象,NSMutableString的對(duì)象就是heap中的對(duì)象徙邻。前者創(chuàng)建時(shí)分配的內(nèi)存長(zhǎng)度固定且不可修改排嫌;后者是分配內(nèi)存長(zhǎng)度是可變的,可有多個(gè)owner,適用于計(jì)數(shù)管理內(nèi)存管理模式缰犁。
兩類對(duì)象的創(chuàng)建方法也不同淳地,前者直接創(chuàng)建“NSString * str1=@"welcome";“,而后者需要先分配再初始化“NSMutableString * mstr1=[[NSMutableString alloc] initWithString:@"welcome"];”帅容。
(miki西游 @mikixiyou 原文鏈接:http://mikixiyou.iteye.com/blog/1595230)
再補(bǔ)充一點(diǎn)颇象,這里說(shuō)的是操作系統(tǒng)的堆和棧。
在我們學(xué)習(xí)“數(shù)據(jù)結(jié)構(gòu)”時(shí)并徘,接觸到的堆和棧的概念和這個(gè)操作系統(tǒng)中的堆和棧不是一回事的遣钳。
操作系統(tǒng)的堆和棧是指對(duì)內(nèi)存進(jìn)行操作和管理的一些方式。
“數(shù)據(jù)結(jié)構(gòu)“的堆實(shí)際上指的就是(滿足堆性質(zhì)的)優(yōu)先Queue的一種數(shù)據(jù)結(jié)構(gòu)麦乞,第1個(gè)元素有最高的優(yōu)先權(quán)蕴茴;棧實(shí)際上就是滿足先進(jìn)后出的性質(zhì)的數(shù)據(jù)或數(shù)據(jù)結(jié)構(gòu)劝评。