这一阶段我们主要来讲讲iOS内存管理方面的知识,面试的时候可能大家多多少少都会被问及这方面的问题,那我们就从常见的面试题开讲
- 使用
、CADisplayLink
有什么注意点?NSTimer
- 介绍下内存的几大区域
- 讲一下你对iOS内存管理的理解
-
都帮我们做了什么?ARC
-
的实现原理weak指针
-
对象在什么时机会被调用autorelease
release
- 方法里有局部对象,出了方法后会
吗?立即释放
上一篇我们说了
定时器
和
CADisplayLink
,今天我们来说说第二条,介绍下
iOS的内存布局
##我们从低向高看依次是
- 内存的低地址是保留的
- 代码段(__TEXT)
编译之后的代码
- 数据段(__DATA)
字符串常量:比如NSString *str = @“123”
已初始化数据:已初始化的全局变量、静态变量等
未初始化数据:未初始化的全局变量、静态变量等
- 堆(heap)
通过、
alloc
、
malloc
等动态分配的空间,分配的内存空间地址
calloc
越来越大
- 栈(stack)
函数调用开销,比如。分配的内存空间地址
局部变量
越来越小
- 内核区
保留区和内核区我们是用不到的
##下面我们来写代码验证下
我们新建一个工程,我们就直接在main文件里直接写了
int a = 10;
int b;
int main(int argc, char * argv[]) {
@autoreleasepool {
static int c = 20;
static int d;
int e;
int f = 20;
NSString *str = @"123";
NSObject *obj = [[NSObject alloc] init];
NSLog(@"\n&a=%p\n&b=%p\n&c=%p\n&d=%p\n&e=%p\n&f=%p\nstr=%p\nobj=%p\n",
&a, &b, &c, &d, &e, &f, str, obj);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
然后我们运行下看终端日志输出
/*
字符串常量
str=0x10dfa0068
已初始化的全局变量、静态变量
&a =0x10dfa0db8
&c =0x10dfa0dbc
未初始化的全局变量、静态变量
&d =0x10dfa0e80
&b =0x10dfa0e84
堆
obj=0x608000012210
栈
&f =0x7ffee1c60fe0
&e =0x7ffee1c60fe4
*/
我们可以看到跟我们画的图是一样的
- 字符串常量的内存地址 < 已初始化的全局变量、静态变量 < 未初始化的全局变量、静态变量 < 堆 < 栈
- 我们还发现
和全局变量
的内存地址是静态变量
,所以我们可以说挨着的
(不管放在那里方法内部也好外部也好)和静态变量
是一样的内存是全局变量
的,编译完以后它们就已经确定了放在了一块的只有一份
- 还有就是我们看到
到数据段
和堆
的地址跨度非常大,所以系统留给我们的栈
和堆
的空间是栈
的非常大
- 还有一点就是由于
分配的空间地址堆
,而越来越大
分配的空间地址栈
,也就是说越来越小
和堆
之间的地址有可能是栈
,也可能是堆空间
栈空间
One More Thing
喜欢的朋友可以扫描关注我的公众号(多多点赞,多多打赏,您的支持是我写作的最大动力)