不同數(shù)據(jù)類型占用字節(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ù)倍地址開始存儲)
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ù)倍表牢,不足要補齊
iOS獲取內(nèi)存大小的三種方式
sizeof
: 是C/C++中的一個操作符(operator),簡單的說其作用就是返回一個對象或者類型所占的內(nèi)存字節(jié)數(shù)贝次。在編譯階段 就會確定大小
class_getInstanceSize
: 這個方法由runtime提供api,用于獲取實例對象所占的內(nèi)存大小崔兴,本質(zhì)是獲取實例對象中成員變量的內(nèi)存大小
(注
:如自定義類或繼承關(guān)系 屬性的多少變化而變化,如單純的繼承NSObject并且沒有任何屬性 打印為8 因為 有隱藏 isa 萬物皆對象蛔翅,而對象的本質(zhì)為 繼承 objc_object 的結(jié)構(gòu)體 它就是對象模板)
malloc_size
: 獲取系統(tǒng)實際分配的內(nèi)存大小(16字節(jié)對齊
)
拓
: 我們知道alloc 流程 最重要的三部曲
cls->instanceSize:計算需要開辟的內(nèi)存空間大星们选(這里有一個算法為16字節(jié)對齊)
calloc:申請內(nèi)存,返回地址指針
obj->initInstanceIsa:將 類 與 isa 關(guān)聯(lián)
結(jié)構(gòu)體內(nèi)存對齊
首先創(chuàng)建 3個結(jié)構(gòu)體 這三個結(jié)構(gòu)體內(nèi)部參數(shù)類型 都一樣 只不過 是順序不一樣
[圖片上傳中...(截屏2020-09-15下午2.17.31.png-4046a7-1600150682775-0)]
{
char a; //1
double b;//8
int c; //4
short d; //2
}Mystruct1;
struct Mystruct2{
double b;//8
char a; //1
int c; //4
short d; //2
}Mystruct2;
struct Mystruct3{
char a; //1
short d; //2
int c; //4
double b;//8
}Mystruct3;
根據(jù)內(nèi)存規(guī)則 我們畫圖來分析
分析: ofsize 0
開始 存儲char
類型占一個
字節(jié)的a
; b
要存儲了 首先分析自己自身多大
我是double
類型的 我需要占8
個字節(jié) 可是 如果從 a
后面 開始 不滿足自身 8 的倍數(shù)
的地方 那我只能往下數(shù) 看來只能到 8的位置開始 容納我的身體 【8 - 15 】
; 該c
出廠 存儲了 我自身占用 4字節(jié)
我是int
類型的 我只能先從16 開始 我的天 真幸運 正好符合我自身4字節(jié)的倍數(shù)
我可以 存儲了 【16- 19】
d
出場了 我自身占 2個字節(jié)
得需要從20 位開始找能不能滿足 我的倍數(shù)的規(guī)則要求
20 除 2 可以的 我也可以放下了 【20 - 21】
Mystruct1 結(jié)構(gòu)體
承載了 21+1 個字節(jié)
突然 大喇叭喊出規(guī)則:結(jié)構(gòu)體的總大小
山析,也就是sizeof的結(jié)果堰燎,必須是內(nèi)部最大成員的整數(shù)倍,不足要補齊
:好的 那我里面最大的是 8 字節(jié) 那么 我現(xiàn)在 算出來 22 那么 補齊就好了嘛 不要激動 心里默念: 二 八 16笋轨, 不滿足 秆剪; 三八 24 滿足啦 結(jié)束了赊淑。所以 Mystruct1 占用 24個字節(jié)空間
分析: 從 0 的位置開始存 自身是double 類型的占用8個字節(jié)的 b【0-7】
a 是 占用一個字節(jié)的char類型 ,從 8的位置 滿足自身1字節(jié)的倍數(shù) 所以 存儲在8的位置【8】仅讽,c來了 首先 我自己是 int類型 我占用 4個字節(jié) 我只能從 9的位置開始存 可是 不滿足 規(guī)則 必須是自己字節(jié)數(shù)的倍數(shù)陶缺,那我只能往下數(shù)了 9.10.11.12 咦!12是我的位置 那就從12開始【12-15】洁灵, d來了 首先想自己是 short類型的占用2個字節(jié) 我只能先從 16 的位置看 咦饱岸!這么巧 正好符合規(guī)則 是我的倍數(shù) 存這沒毛病
Mystruct2 結(jié)構(gòu)體
承載了 17+1 個字節(jié)
,大喇叭又開始廣播了:結(jié)構(gòu)體的總大小
徽千,也就是sizeof的結(jié)果苫费,必須是內(nèi)部最大成員的整數(shù)倍,不足要補齊
双抽,好的村長 我補齊: 結(jié)構(gòu)體最大的是 double占 用8個字節(jié) 我算出來18百框。 2*8 = 16 不滿足 3 *8 = 24 村長 我滿足了。所以 Mystruct2 占用 24個字節(jié)空間
分析:從0 開始 存入一個 char類型的a d 來了 首先分析自己 是short類型 占用2個字節(jié) 那我如果從1 開始 那不是我的倍數(shù) 不滿足規(guī)則荠诬。所以 往下看 2 好像 是我字節(jié)的倍數(shù) 琅翻,好的存入 【2-3】 c來了我是 int類型的 占4字節(jié) 我只能從4開始存儲 好像也滿足 是我的自身4字節(jié)的倍數(shù) ,好的存入【4-7】柑贞,b來了 嗯我是double類型 我自身占用8字節(jié) 我只能從 8號位置 開始存儲 好像 8也是我的倍數(shù) 好的 存入【8-15】
`Mystruct3 結(jié)構(gòu)體 承載了 15+1個字節(jié)方椎,行了大喇叭別廣播了 我知道了 我內(nèi)部成員最大 的為8字節(jié) 必須是 8字節(jié)的整數(shù)倍 不足要補齊。
2*8 = 16 我滿足了 钧嘶,所以 Mystruct3占用 16個字節(jié)
嵌套結(jié)構(gòu)體
我們已經(jīng)對結(jié)構(gòu)體內(nèi)存很明晰了 那么來個嵌套的
struct Mystruct3{
char a; //1 0
short d; //2 [2 3]
int c; //4 [4 5 6 7]
double b;//8 [8 9 10 11 12 13 14 15]
}Mystruct3;
struct Mystruct4{
char a; //1
int b; //4
struct Mystruct3 struct3; //16
}Mystruct4;
上面我們分析了 Mystruct3 占用 16 個字節(jié) 那么 Mystruct4占用多少呢
分析:
a 是占用一個字節(jié)的char類型 放在【0】
b是 占4字節(jié)的int類型 找到最近的 自身的占用字節(jié)的倍數(shù)的位置 為【4-7】
sturct3 是一個占用 16字節(jié) 的結(jié)構(gòu)體 我們首先分析它最大的成員占多少內(nèi)存 這里 為double 類型 占8個字節(jié) 所以應(yīng)該 從8 的倍數(shù)開始存放第一個元素 上面的b占了【4-7】故只能從8往后數(shù) 正好8的位置 是 sturct3里最大元素的倍數(shù) 故第一個元素位置為【8】第二個元素為short類型占2個字節(jié) 所以需要從8 往后數(shù)正好滿足自身的倍數(shù) 也就是【10 11】 第三個元素為double類型 占8個字節(jié) 所以需要從11 往后數(shù)滿足8 的倍數(shù) 也就是【16 - 23】 因為 sturct3 是個結(jié)構(gòu)體 也滿足內(nèi)存對齊原則 也就是 最大元素的倍數(shù) sturct3占了 16字節(jié) 正好滿足 對齊原則 a 占1 個 空白占3 b 占4 個 加在一起占 24個
sturct4 內(nèi)存對齊 為 最大成員的倍數(shù) 最大成員 為struct3 里double 8 字節(jié) 所以
又是大喇叭所說的 內(nèi)部成員最大字節(jié) 的倍數(shù)
所以 sizeof(Mysturct4) 最終 為 24
注意:
- 嵌套結(jié)構(gòu)體 棠众,最大成員 不是 被嵌套的結(jié)構(gòu)體本身大小 ,而是要看被嵌套的結(jié)構(gòu)體元素 和當前結(jié)構(gòu)體元素 誰大 誰最大就是誰的倍數(shù)
- 被嵌套的結(jié)構(gòu)體 第一個元素占用位置 由 自身最大元素字節(jié)的倍數(shù)開始