获取内存大小的三种方式分别是:
-
sizeof
-
class_getInstanceSize
-
malloc_size
1. sizeof
是一个运算符,并不是一个函数。
sizeof 传进来的是类型,用来计算这个类型占多大内存,这个在 编译器编译阶段
就会确定大小并直接转化成 8 、16 、24 这样的常数,而不是在运行时计算。参数可以是数组、指针、类型、对象、结构体、函数等。
NSLog(@"%zd %zd %zd", sizeof(double), sizeof(int), sizeof(void(*)));
// 输出 8 4 8
不难发现,double 占 8字节, int 4 字节,void(*) 代表指针占8字节
它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。
由于在编译时确定占用内存大小,因此sizeof不能用来返回动态分配的内存空间的大小。
2. class_getInstanceSize
用于获取类的实例对象
所占用的内存
大小,并返回具体的字节数,其本质就是获取实例对象中成员变量的内存大小
依赖于<objc/runtime.h>,返回创建一个实例对象所需内存大小
NSObject *objc = [[NSObject alloc] init];
NSLog(@"sizeof: %zd", sizeof(objc));
NSLog(@"class_getInstanceSize: %zd", class_getInstanceSize([objc class]));
打印输出结果:
sizeof: 8
class_getInstanceSize: 8
我们可以通过查看iOS开源的objc4源码了解 class_getInstanceSize()
具体是怎么计算的
- 搜索
class_getInstanceSize
函数
- 搜索
size_t class_getInstanceSize(Class cls)
{
if (!cls) return 0;
return cls->alignedInstanceSize();
}
- 调用了
alignedInstanceSize
函数
- 调用了
uint32_t unalignedInstanceSize() const {
ASSERT(isRealized());
return data()->ro()->instanceSize;
}
// 返回一个类的ivar(成员变量)所占空间的大小
uint32_t alignedInstanceSize() const {
return word_align(unalignedInstanceSize());
}
- 计算占用内存大小 (采用8字节对齐)
# define WORD_MASK 7UL
// 计算占用内存大小算法 (8字节对齐)
static inline uint32_t word_align(uint32_t x) {
// (8 + 7) & ~ 7
return (x + WORD_MASK) & ~WORD_MASK;
}
计算出的占用内存大小是8
image.png3. malloc_size
计算对象实际分配的内存大小
,这个是由系统完成的(采用16字节对齐),
依赖于<malloc/malloc.h>,返回系统实际分配的内存大小
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;
}
image.png算法原理:先右移4位 k = (size + 15) >> 4 , 然后结果左移4位 k << 4 ,其中 右移4位 左移4位相当于将后4位抹零,跟 k/16 * 16一样 ,是16字节对齐算法,小于16就成0了
网友评论