這是我參與8月更文挑戰的第3天,活動詳情查看:8月更文挑戰 上文咱們倆節了內存對齊的一些內容,今天來繼續學習。markdown
已知系統會根據數據類型跳過部份內存,那跳過的部分爲何不能存儲數據?函數
如上圖所示,對於不優化連續存儲的狀況,CPU
讀取8~15
的內存數據,須要先讀取1字節再讀取4字節
,CPU對於要讀取的數據大小是有變化的。而優化後CPU先讀取4字節(因爲白色3字節空白因此能夠直接讀取4字節)再讀取4字節
再這段內存中是沒有變化的。相比於第一種狀況,優化後CPU要進行的操做變少了,這就實現了通過空間換取時間
。post
分析了內存對齊原理,下面咱們來看一下系統是如何開闢內存的。學習
PDObject
定義以下:優化
@interface PDObject : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) long height;
@end
複製代碼
調用:atom
#import "PDObject.h"
#import <objc/runtime.h>
#import <malloc/malloc.h>
PDObject *pdObj = [PDObject alloc];
pdObj.name = @"HotpotCat";
pdObj.age = 18;
NSLog(@"sizeof:%zu class_getInstanceSize:%zu malloc:%zu",sizeof(pdObj),class_getInstanceSize([PDObject class]),malloc_size((__bridge const void *)(pdObj)));
複製代碼
那麼sizeof、class_getInstanceSize、malloc_size分別輸出多少呢? 驗證:spa
sizeof:8 class_getInstanceSize:40 malloc:48
複製代碼
pdObj
是一個結構體指針sizeof
返回8
。class_getInstanceSize
因爲存在isa
和8字節對齊
因此返回40 。malloc_size
爲何返回48
呢?在系統的內存堆區中對象的內存是16字節對齊,成員變量是以8字節對齊(結構體內部)。對象與對象是16字節對齊。3d
爲何對象不以8字節對齊?而以16字節對齊?指針
假如一個對象內部成員變量都是8字節大小。code
對於64字節的空間:
16 32 48 64
8 16 24 32 40 48 56 64
複製代碼
以8字節對齊須要訪問8次,以16字節對齊須要訪問4次
NSObject
,可是不多有對象只有一個isa
。因此最小的對象都應該是16。sizeof
:是運算符,不是函數。獲取對象的長度(對象自己)。class_getInstanceSize
:獲取類的實例所佔用的內存大小。大小隻與成員變量有關。malloc_size
:alloc中實際開闢的空間。calloc
16字節對齊,最小返回16.
segregated_size_to_fit
中。以16字節對齊向上取整