在上一篇文章 juejin.cn/post/697477… 中我们验证了一个NSObject对象占用16个字节的内存。那么我们这次来验证,自定义类占用多少内存?
-
首先我们创建一个Student类,并创建一个Student对象
@interface Stuednt : NSObject{ @public int _no; int _age; } @end @implementation Stuednt @end int main(int argc, const char * argv[]) { @autoreleasepool { Stuednt *stu = [[Stuednt alloc] init]; } return 0; }
-
将OC代码转换成C++源码进行分析:
执行命令:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
得到C++源码如下:
struct Stuednt_IMPL { struct NSObject_IMPL NSObject_IVARS; int _no; int _age; }; /* @end */ // @implementation Stuednt // @end int main(int argc, const char * argv[]) { /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; Stuednt *stu = ((Stuednt *(*)(id, SEL))(void *)objc_msgSend)((id)((Stuednt *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Stuednt"), sel_registerName("alloc")), sel_registerName("init")); } return 0; }
-
查看
NSObject_IMPL
结构体,其结构如下:struct NSObject_IMPL { Class isa; };
所以我们就可以把
Stuednt_IMPL
的结构理解为:struct Stuednt_IMPL { Class isa; int _no; int _age; };
整个转换过程,如下图所示:
-
Student内存布局如下:
-
我们知道
指针
占内存大小为8个字节
,int
占内存大小为4个字节
,所以我们可以推断出Stuednt
对象的成员变量
占用的内存大小为:8+4+4 =16个字节
。 -
在编译器中进行验证:
Stuednt *stu = [[Stuednt alloc] init]; NSLog(@"%zd", class_getInstanceSize([Stuednt class])); NSLog(@"%zd", malloc_size((__bridge const void *)(stu)));
得到结果:
16
16
所以我们得出了结论:Student对象的内存占用大小为
16字节
-
接下来我们再验证一下,Person对象的内存占用大小为多少?
@interface Person : NSObject{ @public int _no; int _age; int _name; } @end
直接在编译器中进行验证:
Person *per = [[Person alloc] init]; NSLog(@"%zd", class_getInstanceSize([Person class])); NSLog(@"%zd", malloc_size((__bridge const void *)(per)));
得到结果:
24
32
按照我们的推断来计算,8+4+4+4 =
24个字节
,那么为什么会占用32个字节
呢? -
原因:这是因为系统内存对齐的原因导致的,执行
alloc
分配内存空间时,操作系统为了方便、快速的管理内存,在分配堆空间时,是一块一块的分配的,而不是一个字节一个字节的分配,这样操作系统对其的操作速度会最快。而在iOS系统
中,每块内存都是16
的倍数。所以当需要24个字节
大小的内存空间时,操作系统就会分配32个字节
。- 相关线索:在苹果的libmalloc源码中,可以找到对应宏的注释:每块内存为16的倍数,最大为256:
-
最后总结一下这两个获取内存占用大小的方法:
class_getInstanceSize
:创建一个实例对象,至少需要多少内存?malloc_size
:创建一个实例对象,实际上分配了多少内存?
-
补充:如果想查看其他操作系统的内存对齐方式,可以在
GNU
官方网站中下载对应库的源码:www.gnu.org/software/li…