struct Struct1{
double a; // 8字節
char b; // 1字節
int c; // 4字節
short d; // 2字節
}struct1;
複製代碼
內存存取粒度:CPU讀取內存時,以'一塊一塊'的進行讀取,‘塊’的大小能夠是一、二、四、八、16...個字節,這樣的塊就是內存讀取粒度markdown
CPU在讀取數據時,首先從內存讀取粒度8開始讀取,讀出了a的數據,而後使用一樣的讀取粒度讀取後邊的數據時,發現b、c、d讀不到,因此要修改內存讀取粒度,從8降到4,這時讀取b就包含了c的數據,這是不對的,直到修改內存讀取粒度爲1時,才能讀獲得b,接下來讀c時,內存讀取粒度就不夠了,須要加大粒度值兩次到4,才能讀取到c...優化
由上咱們能夠知道,每次在讀取時,咱們可能都要同步調整內存讀取粒度
,纔不會讀取越界,這樣CPU的內存訪問速度會受到很是大的影響,讀取的時間會很長,而且出錯的風險也會很大.spa
起始位置
要從該成員大小或者成員的子成員的整數倍開始內部最大成員數據類型所佔內存大小的整數倍地址
開始存儲由內存對齊的規則,咱們再來看上邊的結構體是如何對齊存儲的.3d
double a
char b
當存儲到char b時,CPU讀到了8的位置,8做爲1的整數倍(char 爲1字節),能夠直接從8的位置存儲一個字節 指針
int c
當存儲到int c時,CPU讀到了9的位置,由規則1數據成員存儲的起始位置要從該成員大小的整數倍開始
,9並非int大小(4)的整數倍,則padding,十、11同理,直到12的位置,纔會開始存儲int c code
short d
當存儲到short d時,CPU讀到了16的位置,16是short大小(2)的整數倍,能夠直接存儲 orm
那麼,此時這個struct的總大小,由規則3總大小必須是其內部最大成員的整數倍,不足要補齊
,其中最大的數據成員是double 8個字節,最後的成員數據d的位置在17.以8字節最大整數倍補齊
,因此這個結構體的總大小爲24字節.對象
此時內存對齊後讀取數據時,使用8個內存讀取粒度讀取a; 讀取b、c時只會修改一次內存讀取粒度4,讀取b時會把九、十、11也讀下來,雖然浪費了三個字節的內存,可是一樣也提升了讀取的效率.利用空間換時間
來進行優化.內存
struct Struct2{
double a; // 8字節
int c; // 4字節
short d; // 2字節
char b; // 1字節
}struct2;
複製代碼
Struct2和Struct1中數據成員類型如出一轍,惟一不一樣的是排列的順序差別.依據一樣的對齊規則存儲結果以下: 因此Struct2的總大小爲16字節.同步
這裏能夠獲得這樣的結論:結構體內存大小與結構體成員內存大小的順序有關
這裏咱們看到
0x0000001300006261
指針指向的是亂碼數據,那麼,person的int屬性age,char屬性c一、c2
在哪?
OC對象的本質就是一個結構體
如上圖咱們能夠看到,person的int屬性age,char屬性c一、c2
重排優化在了一個16位數據中.c1,c2的結果是以ASCII碼錶示.
struct Struct3{
double a; // 8字節
char b; // 1字節
int c; // 4字節
short d; // 2字節
struct Struct1 str; //
}struct3;
複製代碼
Struct3結構體中也包含了Struct1結構體,這樣要如何進行內存對齊呢?
a、b、c、d的內存對齊同上,這裏咱們主要看結構體數據成員str.
由內存對齊規則二:
若是一個結構體裏存在結構體成員,則結構體成員要從其內部最大成員數據類型所佔內存大小的整數倍地址
開始存儲. Struct1結構體中最大的數據類型是double--8字節,存儲到d的位置在17.因此存儲Struct1結構體第一個數據double a時,1八、1九、20、2一、2二、23都會被padding.具體以下:
一樣由內存對齊規則三:結構體的總大小,必須是其內部最大成員的整數倍,不足要補齊.因此Struct3結構體的總大小爲48.
struct Struct1{
char b;
int c;
short d;
}struct1;
struct Struct2{
int c;
double a;
char b;
struct Struct1 struct1;
short d;
}struct2;
複製代碼
以上兩個結構體,一樣是結構體struct2中包含告終構體struct1做爲數據成員,不過並非放在最後一個位置。這樣存儲結構體struct2,結果會有什麼不同嗎?
struct2中,c、a、b存儲後的結果到16個字節。重點分析以後如何存儲:
其內部最大成員數據類型所佔內存大小的整數倍地址
開始存儲.因此struct1開始存儲的位置不從17
而是從20
開始。以下:注意
此時存儲到最後一個數據成員short d
時,並非從30開始存儲,由於結構體struct1內部還未作到的內存對齊
。
struct的總大小必須是內部最大成員的整數倍,不足要補齊
。因此當struct1以4字節最大整數倍補齊
後,因此struct1的總大小爲12字節。而後從32開始存儲struct2最後一個數據成員short d
,存儲位置爲[32,33]
。一樣由內存對齊規則三,struct2以8字節最大整數倍補齊
後,struct2的總大小爲40字節。