在描述內存分配之前,我們需要搞懂兩個東西,
RAM
,ROM
。
一、存儲器
- RAM: 隨機存取存儲器(
random access memory
)又稱作“隨機存儲器”,是與CPU
直接交換數據的內部存儲器,也叫主存(內存)。它可以隨時讀寫,而且速度很快,通常作為操作系統或其他正在運行中的程序的臨時數據存儲媒介。存儲單元的內容可按需隨意取出或存入,且存取的速度與存儲單元的位置無關的存儲器。這種存儲器在斷電時將丟失其存儲內容,故主要用于存儲短時間使用的程序 - ROM: 只讀存儲器(
Read-Only Memory
),是一種只能讀出事先所存數據的固態半導體存儲器。其特性是一旦儲存資料就無法再將之改變或刪除。通常用在不需經常變更資料的電子或電腦系統中,并且資料不會因為電源關閉而消失,CPU
是不能直接訪問的,而是需要文件系統/驅動程序(嵌入式中的EMC
)將其讀到RAM
里面,CPU
才可以訪問。
看一下CPU
、RAM
、ROM
之間的關系圖
CPU、RAM、ROM.png
二、程序(App)啟動運行
App
安裝到手機后,存儲在 ROM
中,程序啟動后,系統會把App
程序從ROM
里面拷貝到RAM
,然后從RAM
里面執行代碼。
三、RAM內存分布
RAM內存中分5個區
- 棧區(stack):
- 存放的局部變量、函數的參數值、函數跳轉地址
- 先進后出,一旦出了作用域就會被銷毀
- 棧區地址從高到低分配
- 自動管理內存
- 堆區(heap):
- 堆區的內存分配使用的是alloc;
- ARC的內存的管理,是編譯器再便宜的時候自動添加 retain、release、autorelease;
- 堆區的地址是從低到高分配)
- 需要程序猿管理內存;
- 全局區/靜態區(static):
- 存放全局變量和靜態變量(未初始化過 、初始化過)
- 初始化的全局變量和靜態變量存放在一塊區域,未初始化的全局變量和靜態變量在相鄰的另一塊區域
- 程序結束后由系統釋放
- 常量區:常量字符串就是放在這里;
- 存放常量字符串
- 程序結束后由系統釋放
- 代碼區:
- 存放App代碼
- 程序結束后由系統釋放
image.png
#import "ViewController.h"
@interface ViewController ()
@end
NSInteger a = 10; //全局初始化區
NSArray *array; //全局未初始化區
@implementation ViewController
- (void)viewDidLoad {
//UIView *subView 指針存在棧區, [[UIView alloc] init] 對象保存在堆區
UIView *subView = [[UIView alloc] init];
NSString *string = @"8888"; // string存在棧上, @"8888" 在常量區。
static NSInteger count = 0; // 全局(靜態)初始化區, 0 在常量區
}
@end
四、注意事項:
1.棧區中的變量由編譯器負責分配和釋放,內存隨著函數的運行分配,隨著函數的結束而釋放,由系統自動完成。只要棧的剩余空間大于所申請空間,系統將為程序提供內存,否則將報異常提示棧溢出
2.當App啟動后,代碼區,常量區,全局區大小已固定,而堆區和棧區是時時刻刻變化的(堆的創建銷毀,棧的彈入彈出),所以當使用一個指針指向這兩個區里面的內存時,一定要注意內存是否已經被釋放,否則會產生程序崩潰。