iOS的程序内存分为五大区域,分别为栈,堆,BSS,全局变量,代码区。
分配时间 | 区域名称 | 描述 |
---|---|---|
运行时分配 | 栈 | 局部变量,函数参数 |
运行时分配 | 堆 | 程序代码new出的对象 |
编译时分配 | BSS | 静态变量,未初始化的全局变量 |
编译时分配 | 数据段 | 已经初始化的全局变量,常量 |
编译时分配 | 代码段 | 程序二进制代码 |
栈区的地址一般以0x7开头,堆区的地址一般以0x6开头,这两个区域是函数调用的时候分配,函数执行结束后一般会释放。BSS区域,常量区域内存在程序运行期间一直存在,直到程序运行结束。
使用iOS工程,写一个方法testMethod,放入到ViewController的viewDidLoad中,断点到testMethod可以查看对应的变量。
//文件头部的静态变量和全局变量
//static NSInteger test = 1;
//const NSString *str = @"hello";
- (void)viewDidLoad {
[super viewDidLoad];
[self testMethod:@"method"];
}
- (void)testMethod:(NSString *)param
{
NSString *local = [[NSString alloc] initWithFormat:@"%@", @"hello world!"];
NSString *localstr = [[NSString alloc] initWithFormat:@"%@", @"hello"];
//局部变量
NSInteger tmpInt = 2;
//堆变量
NSLog(@"%@", local);
//taggedPointer
NSLog(@"%@", localstr);
//全局变量
NSLog(@"%@", str);
//静态变量
NSLog(@"%ld", test);
}
在方法的最后一行打断点,断点执行到的时候,右击debug区域的变量,选择View Memory of "xxxx"可以看到这个变量的内存地址。这里有个变量比较特殊,局部变量localstr在debug 区域可以看到它是NSTaggedPointerString,也没有放在堆区。对于这种较短的字符串,苹果做了优化,没有将他们放到堆区,而是直接把值写入到指针中,以便加快访问速度,并减少内存。