程序在系統(tǒng)中運(yùn)行所需要的空間并不是統(tǒng)一的,而是在內(nèi)存中不同的區(qū)域,不同區(qū)域?qū)?nèi)存空間的管理是不同的,因而需要明確不同數(shù)據(jù)各自的內(nèi)存管理方式。
內(nèi)存區(qū)域
iOS中系統(tǒng)內(nèi)存區(qū)域主要分為以下五個(gè)區(qū)域,棧區(qū)、堆區(qū)、BSS段、數(shù)據(jù)區(qū)以及代碼段,見(jiàn)下圖。

棧區(qū)
由系統(tǒng)分配內(nèi)存并對(duì)內(nèi)存進(jìn)行管理,是一種先進(jìn)后出向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),也就是說(shuō)棧頂?shù)牡刂泛蜅5淖畲笕萘渴怯上到y(tǒng)預(yù)先設(shè)定好了的(1M或2M),是一塊連續(xù)的內(nèi)存區(qū)域,用于存儲(chǔ)局部變量。iOS中的基本數(shù)據(jù)類型,如int、float、struct等類型的局部變量都是存放在棧區(qū)。棧區(qū)特點(diǎn):
優(yōu)點(diǎn):快速高效,開(kāi)發(fā)人員無(wú)需關(guān)注其內(nèi)存的釋放;
缺點(diǎn):數(shù)據(jù)有限制且不夠靈活(數(shù)據(jù)大小與生存期必須是確定的)。??臻g分配方式:
靜態(tài)分配:由編譯器完成,比如auto類型變量的分配;
動(dòng)態(tài)分配:由alloc完成,與堆區(qū)的動(dòng)態(tài)分配不同仍由系統(tǒng)自動(dòng)管理。堆區(qū)
是一種先進(jìn)先出向高地址擴(kuò)展的數(shù)據(jù)機(jī)構(gòu),是一塊不連續(xù)的數(shù)據(jù)區(qū)域。堆最大可達(dá)計(jì)算機(jī)虛擬內(nèi)存的大小。由開(kāi)發(fā)者進(jìn)行空間的申請(qǐng)和釋放,如不進(jìn)行釋放會(huì)造成內(nèi)存泄漏,程序結(jié)束后可能由操作系統(tǒng)回收,iOS中通過(guò)引用計(jì)數(shù)對(duì)對(duì)象的生命周期進(jìn)行管理。堆區(qū)特點(diǎn):
優(yōu)點(diǎn):獲得空間靈活,分配內(nèi)存較大;
缺點(diǎn):容易造成碎片(試想在1-4、7-10都申請(qǐng)了內(nèi)存,而我要申請(qǐng)8字節(jié)的大小的內(nèi)存,其中5-8的內(nèi)存相對(duì)來(lái)說(shuō)就成了碎片,只得到其他地址申請(qǐng)4字節(jié)的內(nèi)
存),效率降低。堆空間分配方式:
動(dòng)態(tài)分配:由alloc分配內(nèi)存,速度較慢。BSS段
沒(méi)有初始化的全局變量和靜態(tài)變量存儲(chǔ)在這個(gè)區(qū)域,程序退出后釋放。數(shù)據(jù)區(qū)
用于存儲(chǔ)已經(jīng)初始化的全局變量和靜態(tài)變量以及字符串常量,程序退出后釋放。代碼段
用于存放已經(jīng)編譯后的二進(jìn)制代碼,每一個(gè)指令,每一個(gè)單個(gè)函數(shù)、過(guò)程、方法和執(zhí)行代碼都存在這個(gè)內(nèi)存段中直到應(yīng)用程序退出。
一個(gè)程序啟動(dòng)后其BSS段、數(shù)據(jù)區(qū)、代碼段的位置大小已固定,因此指向這些區(qū)的指針就不會(huì)崩潰,而指向堆棧中的指針由于堆棧時(shí)刻在變化(棧的彈入彈出、堆的創(chuàng)建銷(xiāo)毀)導(dǎo)致這些指針容易出現(xiàn)野指針,所有需要注意這些指針的使用。
PS: I am xinghun who is on the road.