本文源自本人的学习记录整理与理解,其中参考阅读了部分优秀的博客和书籍,尽量以通俗简单的语句转述。引用到的地方如有遗漏或未能一一列举原文出处还望见谅与指出,另文章内容如有不妥之处还望指教,万分感谢。
@interface Person : NSObject {
int myIntVar;
NSString *myStringVar;
}
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
获取内存大小的方式
class_getInstanceSize
该方法是<objc/runtime>提供的api,其本质就是获取实例对象中成员变量的内存大小(采用8字节对齐)。
由于Objective-C是动态语言,一个对象的大小可能会随时改变,因此该函数返回的大小值也可能会随时改变
源码探索
class_getInstanceSize的执行流程图
graph LR
class_getInstanceSize --> alignedInstanceSize --> unalignedInstanceSize --> word_align
通过iOS开源的objc4源码来分析其底层实现
#ifdef __LP64__
# define WORD_MASK 7UL
#else
# define WORD_MASK 3UL
#endif
size_t class_getInstanceSize(Class cls) {
if (!cls) return 0;
return cls->alignedInstanceSize();
}
uint32_t alignedInstanceSize() const {
return word_align(unalignedInstanceSize());
}
// 获取未对齐的类的内存大小即所有成员变量所占内存
uint32_t unalignedInstanceSize() const {
return data()->ro()->instanceSize;
}
// 采用8字节对齐
static inline uint32_t word_align(uint32_t x) {
return (x + WORD_MASK) & ~WORD_MASK;
}
实例
size_t size = class_getInstanceSize([Person class]);
NSLog(@"The size of Person instance is %zu bytes.", size);
// 打印结果: The size of Person instance is 40 bytes.
// 计算未对齐的类的内存大小 unalignedInstanceSize:
// isa + int + NSString + NSString + NSInteger = 8 + 4 + 8 + 8 + 8 = 36
// 字节对齐 word_align(36): (36 + 7) & ~7 = 43 & ~7 = 40
malloc_size
用于获取指针指向的内存块的大小,其本质获取系统实际分配的内存大小(采用16字节对齐)
size_t mallocSize = malloc_size(( **__bridge** **const** **void***)p);
NSLog(@"The size of allocated memory is %zu bytes.\n", mallocSize);
// 打印结果: The size of allocated memory is 48 bytes.
sizeof
- C 语言中的一种运算符,用于返回一个数据类型所占用的内存大小
- 与
class_getInstanceSize方法不同的是,sizeof运算符返回的是指定数据类型本身的大小,与该类型的对象实例是否已经被分配内存无关 - 在编译器的编译阶段就已确定大小,而非运行时确定
语法格式
sizeof(<#expression-or-type#>)
其中,参数expression-or-type可以是任何一个合法的表达式或数据类型,包括基本数据类型、结构体、联合体、数组和指针等。其返回值是一个size_t类型的无符号整数,表示所计算的数据类型或表达式所占据的内存大小,单位是字节。
实例
size(8+8) // 打印结果:1, 8+8=16为Int类型,占4个字节
sizeof(YES) // 打印结果: 1, YES为bool类型,占1个字节
sizeof(NSString *) // 打印结果: 8, 字符串占8个字节
sizeof(person) // 打印结果: 8, person为自定义的对象,本质是结构体指针,占8个字节