OC底层原理02—内存对齐

iOS--OC底层原理文章汇总

为什么要内存对齐?

  • 1.性能方面:提升CPU读取速度。CPU是按照块来读取的,块的大小可以为2,4,8,16。块的大小也称为内存读取粒度。假设某平台硬件CPU读取粒度为8,如果没有内存对齐:
    1)CPU从0-7读取数据,正常取出;
    2)如果数据从第2字节开始,CPU先读取0-7,再读取8-15字节的数据,然后将2-10字节的数据组合为正确的数据返回。
    这样就导致CPU进行了两次读取,效率很低。如果是数据的内存是对齐,CPU可一次性的读取出数据,虽然数据占用多余的内存空间导致一些内存碎片化,但是通过内存空间换取速度的方式是非常可取的。现在的手机、电脑也是通过扩容内存来换取读写速率的提升。
  • 2.平台硬件:不同的硬件平台对任意地址的数据读取不一,不是所有的硬件平台都可以访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些类型的数据,否则抛出硬件异常。

内存对齐原理

万物都有规则,内存对齐也有其规则:
NO.1:数据成员对⻬规则。结构(struct)(或联合(union))的数据成员,第
⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要
从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存储。
NO.2:结构体作为成员。如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整数倍地址开始存储。(若struct a⾥存有struct b,b⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.)
NO.3:结构体的总⼤⼩(sizeof的结果)必须是其内部最⼤成员的整数倍。不⾜的要补⻬。
现在来看看结构体内存的计算和对齐:
假设有两个结构体

struct StructOne{
  double a; // 8字节
  int    b; // 4字节
  short   c; // 2字节
  char   d; // 1字节
}structOne;

struct StructTwo{
  int    a; // 4字节
  double b; // 8字节
  char   c; // 1字节
  short   d; // 2字节
}structTwo;

其中结构体指针长度为8,结构体的内存尺寸则是其内部属性的集合。
sizeof(structOne) = 16;sizeof(structTwo) = 24
结果有点小惊喜和意外,都是一样的成员,因为排序不一样,其内存大小也不同。这是系统按照内存对齐做了“优化”的结果。
对照对齐规则:

structOne的字节分析

上图中是对structOne所占字节分析,该类型占用大小为[0,14],安卓内存对齐原则,其类型所需要的内存大小为最大成员字节大小的整数倍,故而16满足0-14的内存需求。
同理可得sizeof(structTwo)的内存所占位[0,18],共19个长度,安装规则其需求为24字节。

structTwo的字节分析

如果一个结构体嵌套了structOne组成了,按照规则structOne将为structThree中最大的内存成员,其中structOne中最大成员为double类型字节数为8,structThree实际所要的内存空间分别为:
int a; -> [0,1,2,3],
double b; -> 4,5,6,7,[8,9,10,11,12,13,14,15],
struct StructOne one; -> [16,17...30,31]
共占用32个字节,
最大成员内存8的最小整数倍为32,所要structThree的内存空间大小为32。

struct StructThree{
  int    a; // 4字节
  double b; // 8字节
  struct StructOne one; // 16
}structThree;

拓展:内存计算

定义一个Book类,有以下属性,并在VC中实例化它。

// Book.h
@interface Book : NSObject

@property (nonatomic,copy) NSString * bookName;

@property (nonatomic,copy) NSString * bookAuth;

@property (nonatomic,assign) float  bookVersion;

@property (nonatomic,assign) int  pageNnumbers;

@end
   // 在VC中调用
   Book * book = [[Book alloc] init];
   book.bookName = @"Objective-C Programming";
   book.pageNnumbers = 256;
  
   NSLog(@"\nbook:%@ \nsizeof: %lu \nclass_getInstanceSize:%lu \nmalloc_size: %lu",book,sizeof(book),class_getInstanceSize([book class]),malloc_size((__bridge const void *)(book)));

执行会得到

2020-09-09 17:48:23 OC_MemoryAlignment[44017:1549093] 
book:<Book: 0x600000652a80> 
sizeof: 8 
class_getInstanceSize: 32 
malloc_size: 32
  • sizeof:是一个运算符,计算的是括号中类型占用内存的大小。此例中book为一个指针类型,故而大小为8;
  • class_getInstanceSize:源码如下:
/** 
 * Returns the size of instances of a class.
 * 
 * @param cls A class object.
 * 
 * @return The size in bytes of instances of the class \e cls, or \c 0 if \e cls is \c Nil.
 */
OBJC_EXPORT size_t
class_getInstanceSize(Class _Nullable cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

它是runtime中的一个方法,获取的是类实例实际占用内存大小(字节单位)。Book中定义了4个属性,class_getInstanceSize计算就是Book类实例四个属性实际占用内存大小为32字节。(1个属性对应8个字节大小)

  • malloc_size源码中这样写道:
extern size_t malloc_size(const void *ptr);
    /* Returns size of given ptr */

它返回的则是实际类实例开辟的内存空间大小。

总结
sizeof-> 类型占用内存的大小
class_getInstanceSize -> 实际占用内存大小(字节单位)。
malloc_size->实际开辟的内存空间大小。

各类型所占内存空间


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270