iOS内存分配

1.对象占用内存

我们在开发的过程中,会使用到很多的对象,每个对象都需要分配内存,某些情况下,我们需要完成一个业务的时候可能要产生很多的对象,如果大量对象存在的话,会占用一定的内存,所以我们必须要知道一个对象会占用多大内存,从而知道产生的大量对象大概占用多少内存,从而去优化内存。

一个NSObject对象,我们可以用这样的代码去打印一个NSObject对象的大小:

NSObject *o = [[NSObject alloc] init];
NSLog(@"%zd", class_getInstanceSize(o));

打印:8
注意这里并不是实际分配的内存大小,这里只是NSObject占用的内存大小。

使用以下代码查看NSObject分配的内存大小:

NSObject *o = [[NSObject alloc] init];
NSLog(@"%zd", malloc_size((__bridge const void *)(o))); 

打印:16
这里的16个字节才是真正的NSObject的内存大小,严格来说是,真正的分配的内存大小

假设一个业务,需要到1000个NSObject对象,那么就是1000 * 16 = 16000,单位是byte,换算成15.625M。可能有人觉得15M左右可以接受,而且1000个NSObject也太多了,但是一般情况下,我们不产生这么多个NSObject对象,而是产生N个NSObject的子类,那么这个时候就要知道NSObject子类所占的内存大小。

假设有这样的NSObject子类代码:

@interface ObjectChild : NSObject
@property (nonatomic, assign) NSInteger intTest;
@end

用同样的方式,可以知道这个对象真正的分配的内存大小的内存大小为16个字节。

再来如下代码,再增加多一个NSInteger的代码:

@interface ObjectChild : NSObject
@property (nonatomic, assign) NSInteger intTest1;
@property (nonatomic, assign) NSInteger intTest2;
@end

用同样的方式,可以知道这个对象真正的分配的内存大小的内存大小为32个字节。当有4个NSInteger的时候,这个对象真正的分配的内存大小的内存大小为48个字节。

假设一个自定义类是如下代码,它所真正的分配的内存大小就为48个字节

@interface ObjectChild : NSObject
@property (nonatomic, assign) NSInteger intTest1;
@property (nonatomic, assign) NSInteger intTest2;
@property (nonatomic, assign) NSInteger intTest3;
@property (nonatomic, assign) NSInteger intTest4;
@end

重新来算,假如一个业务需要到1000个对象,每个对象48个字节,那么就是48 * 1000 = 48000byte,换算成46.875M。在这个情况下,所占的内存就相当多了。

那么最后给个结论,iOS的内存分配实际上是16个字节的倍数类分配的,假设一个对象用class_getInstanceSize()算出是占8个字节,其实分配了16个字节;假设一个对象用class_getInstanceSize()算出是占17个字节;其实分配了32个字节;假设一个对象用class_getInstanceSize()算出是占40个字节,其实分配了48个字节。如此类推。

其实这个内存分配分两个步骤
  1. runtime会先去计算对象大小是否小于8个字节,如果是分配16个字节。
  2. 实际分配内存的时候调用一个C语言的calloc()函数去分配内存的,这个分配的原则就是16的倍数,当然这里可能还有其他的分配原则。
这样做的好处是什么
  1. 这样是为了字节对齐,可以提高寄存器的访问速度,典型的空间换时间。
  2. 应该有有其他原因,这里没有再去了解。
知道了这个内存分配有什么用

假设我们某个业务需要1000个对象,每个对象大小48个字节(当然有可能是更大),那么一共需要46.875M的话内存消耗比较大,这个时候,我们可以用时间换空间的做法去节省内存,比如某些对象里的属性,其实是在某个功能底下才使用的,那么我们可以使用到某个功能的时候才去计算出来这个值在栈里,然后使用,这样的话每个对象都可以省下这个属性所占的内存大小。
假设本来每个对象大小为48个字节,那么少了一个属性,有可能大小变成了32个字节,这样就一定程度优化了内存。

2.图片占用内存

待续。。。

你可能感兴趣的:(iOS内存分配)