獲取內(nèi)存大小的三種方式分別是:
-
sizeof
-
class_getInstanceSize
-
malloc_size
1. sizeof
是一個運算符,并不是一個函數(shù)焕妙。
sizeof 傳進來的是類型蒋伦,用來計算這個類型占多大內(nèi)存,這個在 編譯器編譯階段
就會確定大小并直接轉(zhuǎn)化成 8 焚鹊、16 痕届、24 這樣的常數(shù),而不是在運行時計算寺旺。參數(shù)可以是數(shù)組爷抓、指針、類型阻塑、對象蓝撇、結(jié)構(gòu)體、函數(shù)等陈莽。
NSLog(@"%zd %zd %zd", sizeof(double), sizeof(int), sizeof(void(*)));
// 輸出 8 4 8
不難發(fā)現(xiàn)渤昌,double 占 8字節(jié), int 4 字節(jié)走搁,void(*) 代表指針占8字節(jié)
它的功能是:獲得保證能容納實現(xiàn)所建立的最大對象的字節(jié)大小独柑。
由于在編譯時確定占用內(nèi)存大小,因此sizeof不能用來返回動態(tài)分配的內(nèi)存空間的大小私植。
2. class_getInstanceSize
用于獲取類的實例對象
所占用的內(nèi)存
大小忌栅,并返回具體的字節(jié)數(shù),其本質(zhì)就是獲取實例對象中成員變量的內(nèi)存大小
依賴于<objc/runtime.h>曲稼,返回創(chuàng)建一個實例對象所需內(nèi)存大小
NSObject *objc = [[NSObject alloc] init];
NSLog(@"sizeof: %zd", sizeof(objc));
NSLog(@"class_getInstanceSize: %zd", class_getInstanceSize([objc class]));
打印輸出結(jié)果:
sizeof: 8
class_getInstanceSize: 8
我們可以通過查看iOS開源的objc4源碼了解 class_getInstanceSize()
具體是怎么計算的
- 搜索
class_getInstanceSize
函數(shù)
- 搜索
size_t class_getInstanceSize(Class cls)
{
if (!cls) return 0;
return cls->alignedInstanceSize();
}
- 調(diào)用了
alignedInstanceSize
函數(shù)
- 調(diào)用了
uint32_t unalignedInstanceSize() const {
ASSERT(isRealized());
return data()->ro()->instanceSize;
}
// 返回一個類的ivar(成員變量)所占空間的大小
uint32_t alignedInstanceSize() const {
return word_align(unalignedInstanceSize());
}
- 計算占用內(nèi)存大小 (采用8字節(jié)對齊)
# define WORD_MASK 7UL
// 計算占用內(nèi)存大小算法 (8字節(jié)對齊)
static inline uint32_t word_align(uint32_t x) {
// (8 + 7) & ~ 7
return (x + WORD_MASK) & ~WORD_MASK;
}
計算出的占用內(nèi)存大小是8
image.png
3. malloc_size
計算對象實際分配的內(nèi)存大小
索绪,這個是由系統(tǒng)完成的(采用16字節(jié)對齊)湖员,
依賴于<malloc/malloc.h>,返回系統(tǒng)實際分配的內(nèi)存大小
malloc
源碼分析中的segregated_size_to_fit
#define SHIFT_NANO_QUANTUM 4
#define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM) // 16
static MALLOC_INLINE size_t
segregated_size_to_fit(nanozone_t *nanozone, size_t size, size_t *pKey)
{
size_t k, slot_bytes;
if (0 == size) {
size = NANO_REGIME_QUANTA_SIZE; // Historical behavior
}
k = (size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM; // round up and shift for number of quanta
slot_bytes = k << SHIFT_NANO_QUANTUM; // multiply by power of two quanta size
*pKey = k - 1; // Zero-based!
return slot_bytes;
}
算法原理:先右移4位 k = (size + 15) >> 4 瑞驱, 然后結(jié)果左移4位 k << 4 娘摔,其中 右移4位 左移4位相當于將后4位抹零,跟 k/16 * 16一樣 唤反,是16字節(jié)對齊算法凳寺,小于16就成0了
image.png