关于内存,首先讲要介绍两个概念虚拟内存, 物理内存。
物理内存:这个就没啥好说的了,就是实际上你的硬件内存是多少那就是多少。
虚拟内存:这个是一种对于物理内存的使用优化方案。先假设有很大的空间可以使用,实际上是有条理的把要使用到的东西放到物理内存中去。
打个比方:你向家里的领导申请了1000块的零花钱,领导也批准了,但是并不会一开始就给你1000块。只会在你真的要出去喝朋友聚餐的时候,需要多少钱就给你多少钱。多的一毛也没有。
进入正题
我们日常生成一个对象都会
习惯性的alloc,init一气呵成。仿佛绝世高手一般丝毫不拖泥带水。
那么有没有想过alloc,init还有一个没什么人用的new,他们到底是做了些什么呢!
alloc的操作实际上就像是向内存进行申请一块内存
当执行alloc操作后,内存就会分配一块内存给对象并返回指针。
但是对于这样的对象,你只能做一些简单的操作
假设有这样一个函数,并在分配好内存后去调用
结果还是可以调用到的,但是如果包含一些对象的操作
最后只能是无能为力了
原因就在于并没有调用到init这个方法,对相应的对象进行初始化。
所以alloc是进行内存的申请,init是做初始化的操作。
那么new呢?
实际上new的功能是等同于 [[ alloc] init]的,但是在很多的情况下,我们要用到的是 [[ alloc] initWith......]这样的形式来进行初始化对象。new的应用场景就显得太过局限了
讲完基本alloc,init,new的区别,那么再来想一个问题,alloc申请的到底是虚拟内存还是物理内存呢
我们可以通过instruments来进行查看
我们先建立这样一个函数
通过按钮来进行控制,每次点击按钮就循环生成100000个对象,然后看看instruments里面有关内存的Persistent Bytes的数据
第一次点击
第二次点击
第三次点击
可以看到,每次点击都稳定的添加1.53M左右的实际内存,最后证明,alloc所申请的是物理内存!
那么,问题又来了,为什么每次建立100000个MemoryModel会占用是1.53M呢,不是1M也不是10M呢
我们先看下Model里面的对象组成
只有一个NSString的对象,我们知道在64位操作系统里面,NSString应该是8字节的,那么我们生成一个MemoryModel对象看看占用多少的内存
什么鬼,为什么最后输出的是16个字节?难道是编译器抽风了?我们再看看如果是两个NSString的对象呢
居然是32?难道是记错了,NSString就是16字节的么?
再加一个int类型的试试
怎么又是32,这回彻底懵逼了。
产生这种诡异的现象的原因是因为苹果在内存分配上是遵循的字节对齐原则的!
当我们分配一块内存的时候,假设需要的内存小于16个字节,操作系统会直接分配16个字节;加入需要的内存大于16个字节,操作系统会分配a*16个字节。
现在我们来算一下前面三个例子为什么会输出16,32,32
每个对象的isa会占用8字节,NSString对象也会占用8字节,int类型占用4字节
1:8 + 8 = 16 这个结果正好就是输出的16
2:8 + 8 + 8 = 24 , 16 < 24 < 32 根据字节对齐规则,最后输出的是32
3:8 + 8 + 8 + 4 = 28, 16 < 28 < 32 根据字节对齐规则,最后输出32
知道了这个规则,那么就能明白你所生成的对象到底会占用多少的内存了。
以上内容,如有虚构,请及时指出,就是这样,喵