iOS內(nèi)存主要分成棧區(qū)、堆區(qū)、全局區(qū)、常量區(qū)、代碼區(qū)這五大區(qū)域。如下圖所示:

棧(Stack)
棧是由高地址向低地址擴(kuò)展的一塊連續(xù)的內(nèi)存區(qū)域,一般在運行時分配,其對應(yīng)的進(jìn)程或線程是唯一的,它遵循先進(jìn)后出(FILO)的原則。
在iOS中棧區(qū)的地址通常以0x7開頭,棧的大小是有限制的,在主線程棧的大小為1MB,子線程棧的大小默認(rèn)為512KB,當(dāng)然可以通過api修改子線程棧的大小(NSThread的stackSize屬性),但棧最小為16KB且為4的倍數(shù)。
棧是編譯器自動分配并釋放的,不需要開發(fā)者管理內(nèi)存,它不會產(chǎn)生內(nèi)存碎片,特點是快速高效。
通常棧區(qū)存放的是臨時變量和函數(shù)參數(shù)。
堆(Heap)
堆是低地址向低地址擴(kuò)展的一塊不連續(xù)的內(nèi)存區(qū)域,同樣在運行時分配,它是一個鏈表結(jié)構(gòu),相比于棧,它速度較慢,但空間更大。
在iOS中堆通常以0x6開頭,它的空間分配總是動態(tài),由于它是鏈表結(jié)構(gòu),所以堆便于增刪,不便于查找。
堆是開發(fā)者動態(tài)分配和釋放,在使用堆時往往要注意內(nèi)存管理,很容易就產(chǎn)生內(nèi)存碎片,比如打上retain時要注意release,當(dāng)然在ARC的情況下,內(nèi)存管理要容易的多。
堆區(qū)通常存放對象本身(注意不是對象指針),OC中使用alloc或new創(chuàng)建的對象、C中使用malloc、calloc開辟的空間,都在堆區(qū)中。
全局區(qū)
全局區(qū)又稱靜態(tài)區(qū),在編譯時分配,此內(nèi)存中的數(shù)據(jù)一致存在,程序結(jié)束后由系統(tǒng)釋放。
全局區(qū)可以分為兩個兩個部分,分別是
- 存放未初始化全局變量和靜態(tài)變量的BSS區(qū)
- 存放已初始化全局變量和靜態(tài)變量的數(shù)據(jù)區(qū)
全局區(qū)存放靜態(tài)變量比如static修飾的變量
常量區(qū)
常量區(qū)是在編譯時分配的一塊內(nèi)存,程序結(jié)束后同樣由系統(tǒng)釋放。
常量區(qū)主要存放字符串常量
代碼區(qū)
代碼區(qū)是存放程序運行的二進(jìn)制代碼,由編譯時分配
棧幀(Stack Frame)
每一次函數(shù)的調(diào)用,都會在調(diào)用棧上維護(hù)一個獨立的空間,這個空間成為棧幀,當(dāng)前運行的函數(shù)總在棧頂,每個獨立的棧幀一般包括
- 函數(shù)的返回地址和參數(shù)
- 臨時變量:包括函數(shù)的非靜態(tài)局部變量和以及編譯器自動生成的其他臨時變量
- 函數(shù)調(diào)用的上下文
靜態(tài)變量不添加到棧幀中