iOS内存管理的基本介绍:
- 1.iOS使用的是虚拟内存:段式虚拟内存+页式虚拟内存。
- 2.iOS没有Swap机制,所以当应用内存占用过多时,会被kill掉。
- 3.iOS内存分类:
Clean Memory:闪存中有备份,能再次读取重建。
例如:Code、framework、memory-mapped files(内存映射文件)
Dity Memory:所有非Clean Memory,在堆内存中,系统无法自动回收。
例如:caches、堆上分配的对象
关于CleanMemory和Dity Memory举个例子:
- (void)memoryAnalyse{
NSString *str1 = [NSString stringWithString:@"Hello"];//1
NSString *str2 = @"Hello";//2
char *buf = malloc(100 * 1024 * 1024);//3
for (int i = 0; i < 5 * 1024 * 1024; i ++) {
buf[i]=rand();//4
}
}
逐行分析上面代码:
- Dity Memory:函数stringWithString内存是分配在堆上的
- Clean Memory:分配在只读数据段
- Clean Memory:buf指向的是100M虚拟内存,只有在使用时,才会映射到物理内存上(对比第四行能更清楚理解这一问题)
- Clean Memory+Dity Memory:前5M为Dity,后95M为Clean
iOS内存段介绍:
内存段.png- _PAGEZERO:零地址,1个页大小,无访问权限
- _TEXT:代码段
- _DATA:数据段
- _MALLOC_TINY:请求小于1个页时,分配到此
- _MALLOC_SMALL:请求大于1个页小于1M时,分配到此
- _MALLOC_LARGE:请求大于1M时,分配到此。
常用的内存优化方法
- 图片读取:
imageNamed//使用缓存,适用于频繁使用的小图片
imageWithContentOfFile//不使用缓存,适用于大图的读取 - 文档读取
+ (nullable instancetype)dataWithContentsOfFile:(NSString *)path;//
+ (nullable instancetype)dataWithContentsOfFile:(NSString *)path options:(NSDataReadingOptions)readOptionsMask error:(NSError **)errorPtr;//映射文件到虚拟内存,大文件时采用 - 内存警告处理
当内存不足时,就会收到内存警告。在iOS中提供了3中内存警告通知方式:
- 在应用程序委托中实现applicationDidReceiveMemoryWarning:方法: 应用程序委托对象中接收内存警告消息
- 在UIViewController子类中实现didReceiveMemoryWarning方法:视图控制器中接收内存警告消息
- 注册UIApplicationDidReceiveMemoryWarningNotification通知:
其它类中使用通知接收内存警告消息
收到内存警告,一般有以下几种处理方法:
- 尽可能多的释放资源,尤其是图片等占用内存较多的
- 释放掉单例对象
- iOS6之后对于隐藏的viewController直接设置self.view=nil
- 循环引用
举个例子:
Car *car = [Car new];
car.name = ^{
[car stop];
};// 对象car在block中持有自身,造成循环引用
解决办法:
Car *car = [Car new];
__weak __typeof (car) weakCar = car;
car.name = ^{
__typeof(car) strongCar = weakCar;
[strongCar stop];
};
网友评论