iOS-探索內(nèi)存對齊原則

前言

我們知道一個NSObject對象創(chuàng)建的時候系統(tǒng)分配了16個字節(jié),實際使用的只有8個字節(jié),可是里面要是添加了屬性之后呢,是多少呢,又是按照什么原則,所以這些是本章需要探索的重點,另外還有結(jié)構(gòu)體,文章末尾也會為大家提供源碼。

探索

一、類

1.創(chuàng)建一個空的iOS項目,然后創(chuàng)建一個類如下:

@interface? HXPerson: NSObject

?//對象占了8字節(jié)(0-7)

@property (nonatomic, copy) NSString *name; // 8 (8,15)

@property (nonatomic, copy) NSString *nickName; //8 (16,23)

@property (nonatomic, assign) int age; //4 (24,27)

@property (nonatomic, assign) long height; //8 因為28不是8的整數(shù)倍,所以從32開始算起

//(32,39)因為實際使用的內(nèi)存要是8的整數(shù)倍,所以實際使用的就是40字節(jié),系統(tǒng)分配的要是16的整數(shù)倍,所以是48,為什么是16的整數(shù)倍呢,具體可以看最新的oc源碼

//@property (nonatomic) char c1;

//@property (nonatomic) char c2;

@end


@implementation HXPerson

@end

2.在main函數(shù)中調(diào)用,需要導(dǎo)入頭文件#import <objc/runtime.h>

#import <malloc/malloc.h>,否則后面兩句會報錯

? HXPerson* person = [HXPerson alloc];

? ? ? ? person.name? ? ? =@"hanxiao";

? ? ? ? person.nickName? =@"hh";

? ? ? ? person.age? ? ? =18;

? NSLog(@"%lu-%lu",class_getInstanceSize([HXPerson class]),malloc_size((__bridge const void *)(person)));

二、結(jié)構(gòu)體

1.創(chuàng)建結(jié)構(gòu)體,如下:

struct?HXStruct1 {

? ? double?a;? // 8 (0-7)

? ? char?b;? ? // 1 [8 1] (8)

? ? // 4 [9 4] 9 10 11 12

? ? //因為9不是4的整數(shù)倍,所以要從12開始算起,也就是12,13,14,15

? ? int?c;

? ? short?d;? ? // 2 [16 2] (16 17)

}struct1;

// 內(nèi)部需要的大小為: 17

// 最大屬性 : 8

// 結(jié)構(gòu)體整數(shù)倍: 24

struct?HXStruct2 {

? ? double?a;? //8 (0-7)

? ? int?b;? ? ? //4 (8 9 10 11)

? ? char?c;? ? //1 (12)

? ? short?d;? ? //2 13 (14 15) - 16

}struct2;

// 15 -> 16

struct?HXStruct3{

? ? double a; //8 (0-7)

? ? int?b;? //4 (8 9 10 11)

? ? char?c;? //1 (12)

? ? short d; //2 13 (14 15) - 16

? ? NSString* (*getName)(void);//8 (16,23)-24

? ? struct?HXStruct1 hxSc;

}struct3;

struct?HXStruct4{

? ? //函數(shù)占8個字節(jié)

?? void(*initWithOptions)(NSDictionary*);//8(0-7)

? ? NSString*(*getDeviceInfo)(void);//8(8-15)

? ? NSString*(*getInitStatus)(void);//8(16-23)

?? ? NSDictionary*(*getConfigInfo)(void);//8(24,31)

}struct4;

2.在main函數(shù)中調(diào)用

?NSLog(@"%lu-%lu",sizeof(struct1),sizeof(struct3));

我們發(fā)現(xiàn)結(jié)構(gòu)體里面嵌套結(jié)構(gòu)體依然滿足原則,只需要耐心數(shù)就行了。

總結(jié)

內(nèi)存對齊原則:

1:數(shù)據(jù)成員對?規(guī)則:結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員,第

?個數(shù)據(jù)成員放在offset為0的地?,以后每個數(shù)據(jù)成員存儲的起始位置要

從該成員??或者成員的?成員??(只要該成員有?成員,?如說是數(shù)組,

結(jié)構(gòu)體等)的整數(shù)倍開始(?如int為4字節(jié),則要從4的整數(shù)倍地址開始存

儲。?min(當(dāng)前開始的位置m n) m = 9 n = 4?

9 10 11 12?

2:結(jié)構(gòu)體作為成員:如果?個結(jié)構(gòu)?有某些結(jié)構(gòu)體成員,則結(jié)構(gòu)體成員要從

其內(nèi)部最?元素??的整數(shù)倍地址開始存儲.(struct a?存有struct b,b

?有char,int ,double等元素,那b應(yīng)該從8的整數(shù)倍開始存儲.)

3:收尾?作:結(jié)構(gòu)體的總??,也就是sizeof的結(jié)果,.必須是其內(nèi)部最?

成員的整數(shù)倍.不?的要補?。

一句話,就是實際使用的內(nèi)存是8的倍數(shù),系統(tǒng)分配的內(nèi)存是16的倍數(shù)(為了安全,防止讀到其他內(nèi)存)。

內(nèi)存占用圖

最后提供下源碼地址,喜歡的麻煩點個贊,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容