autoreleasePool一般你在什么地方使用到?
- 大循环
- 在大循环中如果不调用autorelease,会造成内存泄漏
- 多线程
- 用于释放子线程
内存管理的概念
- 定义:高效快速的管理内存,在适当的时候回收和释放内存资源
- MRC中, 使用"引用计数机制", 需要手动管理内存
- ARC中, 使用"强弱引用机制", 系统自动在合适的地方加上retain,release.
- 常见的引起内存泄漏的原因:
- 循环引用
- 大循环
Objective-C堆和栈的区别?
- 管理方式不同:
- 栈是由系统自动管理,无需手动释放。堆是由程序员手动管理,会出现内存泄漏问题
- 申请大小不同:
- 栈的内存是系统固定好的常数,是一块连续的内存区域,一旦申请空间超过栈空间,会造成栈溢出
- 堆是不连续的内存区域,灵活性大
- 碎片问题:
- 堆中:频繁的alloc/new会造成内存空间的不连续,大量的内存碎片,降低程序效率
- 栈中,先进后出原则,不存在碎片问题
- 分配方式
- 堆是动态分配的,没有静态
- 栈有静态和动态两种分配方式,静态分配如局部变量的分配,是由编译器完成的,动态分配和堆的不同,是由编译器来释放,无需手动实现
- 分配效率
- 栈是计算机的数据结构,计算机会给栈提供技术支持,这就决定了栈的分配效率比堆高,堆的底层是C/C++函数库提供的,其结构很复杂
内存管理的几个原则是什么?
- 谁创建,谁释放,谁引用,谁管理
- 在MRC中,一次retain必须对应一次release消息
- 在ARC中强弱引用(注意strong / weak关键字)
- 当strong修饰的指针指向新值或者不复存在时,其相关联的对象会自动释放
- 当weak修饰的对象,其拥有者指向新值或者不复存在时,weak修饰的对象会自动置为nil
[NSAarry arrayWithObject:<id>] 和 NSMuatableArray *array = [NSMuatableArray array] 这两个方法创建数组后,需要对数组做释放操作吗?
- 不需要,编译器会自动将其添加到自动释放池中
找内存问题
@autoreleasepool {
for (long i = 0; i < largeNumber; i++) {
Person *per = [[Person alloc] init];
[per autorelease];
}}
以上代码有什么内存问题,如何改正?
- 会导致内存泄漏
- 使用autorelease会将对象存放到最近的释放池中,不会使引用计数立即-1, 在大循环执行的过程中内存会持续增高
自动释放池是什么,如何工作的?
- 定义:是OC的一种内存自动回收机制,可以将一些临时对象通过自动释放池回收并统一释放
- 工作原理:当自动释放池被销毁时,池内所有Object都会被release1次, 相当于延迟调用release
常见的出现内存循环引用的场景有哪些?
- 两个对象相互持有, 导致互相无法释放内存
- block中访问外界变量
- delegate没有使用weak修饰
内存管理机制
- 引用计数机制
- 强弱引用机制
- 自动释放池
- 属性参数(属性参数里面隐藏了内存管理的细节)
内存警告的传递过程
- 手机内存不足产生事件-->通知应用程序-->调用应用程序代理方法 -->把事件传递给窗口(UIWindow)-->窗口传给控制器-->调用控制器的内存警告方法