iOS內(nèi)存分為五大區(qū)
棧區(qū)(stack)
堆區(qū)(heap)
全局/靜態(tài)區(qū)(bss)
文字/常量區(qū)(data)
代碼區(qū)(code)
棧區(qū)(stack)
- 棧又稱堆棧, 是用戶存放程序臨時創(chuàng)建的局部變量,也就是說我們函數(shù)括弧“{}” 中定義的變量
(但不包括static聲明的變量,static意味著在數(shù)據(jù)段中存放變量)
。除此以外, 在函數(shù)被調(diào)用時,其參數(shù)也會被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返回值 也會被存放回棧中徒扶。由于棧的后進(jìn)先出特點(diǎn),所以 棧特別方便用來保存/恢復(fù)調(diào)用現(xiàn)場胶台。從這個意義上講,我們可以把堆椏牡溃看成一個寄存根灯、交換臨時數(shù)據(jù)的內(nèi)存區(qū)毕源。 - 指針都存在棧區(qū)岸更,用于指向分配在堆區(qū)的內(nèi)存的地址醇疼。
int a = 10;
// a指針地址是在棧區(qū)的 0x7xxxx
NSLog(@"a=%d,a地址:%p",a,&a);
NSObject *obj = [NSObject new]; // 對象 --
NSLog(@"obj對象-%@硕并,obj指針地址:%p",obj,&obj); // 0x6 堆
打印結(jié)果:
a=10, a地址:0x7ffee2acc1ec
obj對象-<NSObject: 0x600000fbc270>,obj指針地址:0x7ffee2acc1e0
//對象的內(nèi)存地址和對象指針的內(nèi)存地址不是同一個
//而且obj的指針地址0x7xxxx在棧區(qū)秧荆,對象是在堆區(qū)0x6xxxx
//一般情況0x7xxxx 就是棧區(qū)倔毙,0x6xxxx就是堆區(qū)
堆區(qū)(heap)
- 堆是用于存放進(jìn)程運(yùn)行中被動態(tài)分配的內(nèi)存段,它的大小并不固定,可動態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc等函數(shù)分配內(nèi)存時,新分配的內(nèi)存就被動態(tài)添加到堆上(堆被擴(kuò)張); 當(dāng)利用free等函數(shù)釋放內(nèi)存時,被釋放的內(nèi)存從堆中被剔除(堆被縮減)
- 堆向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)辰如,是不連續(xù)的內(nèi)存區(qū)域普监。程序員負(fù)責(zé)在何時釋放內(nèi)存(如用free或delete),在iOS的ARC程序中琉兜,系統(tǒng)自動管理計數(shù)器凯正,計數(shù)器為0的時候,在當(dāng)次的runloop結(jié)束后豌蟋,釋放掉內(nèi)存廊散。堆中的所有東西都是匿名的,這樣不能按名字訪問梧疲,而只能通過指針訪問允睹。
- 對于堆來講,頻繁的new/delete勢必會造成內(nèi)存空間的不連續(xù)性,從而造成大量的碎片 ,使程序效率降低幌氮。
全局/靜態(tài)區(qū)(bss)
- bss段通常是指用來存放程序中
未初始化的全局變量和靜態(tài)變量
的一塊內(nèi)存區(qū)域缭受。 - 通常來說如果不初始化全局變量和靜態(tài)變量,編譯器也會對它們進(jìn)行一個隱式初始化(直接賦值就是顯示初始化)该互,賦給它們一個缺省值米者,是我們這里所說的未初始化。
- bss段在程序執(zhí)行之前會清0宇智,所以未初始化的全局變量(靜態(tài)變量)已經(jīng)是0了蔓搞。所以這種情況還是存放在BSS段,一旦初始化就會從BSS段中回收掉随橘,轉(zhuǎn)存到data段(數(shù)據(jù)段)中喂分。
- bss區(qū)-Block Started by Symbol(未初始化數(shù)據(jù)段):并不給該段的數(shù)據(jù)分配空間,僅僅是記錄了數(shù)據(jù)所需空間的大小机蔗。
文字/常量區(qū)(data)
- 數(shù)據(jù)段分為
只讀數(shù)據(jù)段(常量區(qū))
和讀寫數(shù)據(jù)段
- 通常是指用來存放程序中已經(jīng)初始化的全局變量和靜態(tài)變量的一塊內(nèi)存區(qū)域蒲祈。數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配,可以分為只讀數(shù)據(jù)段和讀寫數(shù)據(jù)段甘萧。字符串常量等,是放在只讀數(shù)據(jù)段中,結(jié)束程序時才會被收回讳嘱。
代碼區(qū)(code)
-
通常是指用來存放程序執(zhí)行代碼的一塊內(nèi)存區(qū)域幔嗦。這部分區(qū)域的大小在程序運(yùn)行前就已經(jīng)確定,并且內(nèi)存區(qū)域通常屬于只讀, 某些架構(gòu)也允許代碼段為可寫,即允許修改程序酿愧。在代碼段中,也有可能包含一些只讀的常數(shù)變量,例如字符串常量等,這些常量放在只讀數(shù)據(jù)段(data segment)中沥潭,也有叫做常量區(qū)的說法。