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

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