一、什么是内存对齐
内存对齐是一种在计算机内存中排列数据(表现为变量的地址)、访问数据(表现为CPU读取数据)的一种方式。
它包含了两种相互独立又相互关联的部分:基本数据对齐和结构体数据对齐 。
二、为什么我们要进行内存对齐?
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
三、iOS中实例对象的本质
首先举个例子,我们来以ZXClass进行研究
@interface ZXClass : NSObject
{
int time;
}
@end
@implementation ZXClass
ZXClass *obj = [[ZXClass alloc] init];
@end
接下来我们分别使用
class_getInstanceSize([ZXClass class])
malloc_size((__bridge const void *)obj)
进行打印操作,答应出来的结果分别是12和16,为什么打印出来的结果会有所不同呢。
接下来我们先对于ZXClass进行分析,在iOS中实例对象相当于是一个结构体,我们将刚刚所写的代码通过终端敲入
clang -rewrite-objc main.m -o main.cpp
指令后,生成如下代码
struct ZXClass_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int time; // 4个字节
};
structNSObject_IMPL {
Class isa; // 8个字节
};
根据上面生成的个结构体可以直观的看出一个ZXClass在内存中所占用的大小应该是4Byte(int) + 8Byte(isa) = 12Byte,这么看出来之前getInstanceSize方法所打印出来的结果应该是正确的,为什么会出现malloc_size的16结果呢?
这里就牵扯到iOS中的内存对齐这个概念了。
四、iOS中所运用的内存对齐
带着上面的问题,我们打开苹果开源下载网站(https://opensource.apple.com/tarballs/libmalloc/)进行下载
在 nano_malloc.c中我们可以找到很多关于内存分配的判断函数,根据分析,最后得出一个结论iOS中对于内存分配有对齐的概念,也就是说所分配的内存空间要满足以下两个条件:
1⃣️所分配的内存空间要大于等于对象所真正需要占用的内存空间
2⃣️所分配的内存空间必须要是16*n的结构
这样,我们再反过头来看上面的这个问题,ZXClass中定义了一个int 类型的变量所占内存为4Byte 一个继承自父类NSOjbect的isa所占内存为8Byte,所以真实需要的内存地址为12Byte,又因为第二点规定,所以内存分配的空间为16Byte.
也就是说系统给ZXClass分配了16个字节,而它本身只占用了12个字节,剩下4个为空。
了解这些规律以后,在今后的开发中要尽可能的去进行优化
网友评论