自定义类的内存占用
演示代码1
默认为arm64
。
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <malloc/malloc.h>
@interface Student : NSObject
{
@public
int _age;
int _sex;
}
@end
@implementation Student
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *student = [[Student alloc] init];
NSLog(@"%zu",class_getInstanceSize([Student class]));
NSLog(@"%zu",malloc_size((__bridge const void *)student));
}
return 0;
}
//打印结果为 16 16
-
OC代码转化成C++的代码
将代码转化成C++的代码会找到如下的代码块
struct Student_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _age;
int _sex;
};
代码块中有age
、sex
、NSObject_IMPL
这三个属性。age
和sex
的类型是int
类型,所以每个占用4
个字节的内存,而NSObject_IMPL
占用的是8
个字节。合起来就是16个字节。而alloc
方法返回的最小的内存大小也是16
所以两个方法返回的内存大小都是16
演示代码2
@interface Person : NSObject
{
int _sex;
}
@end
@implementation Person
@end
@interface Student : Person
{
@public
int _age;
}
@end
@implementation Student
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc] init];
NSLog(@"%zu",class_getInstanceSize([Person class]));
NSLog(@"%zu",malloc_size((__bridge const void *)person));
Student *student = [[Student alloc] init];
NSLog(@"%zu",class_getInstanceSize([Student class]));
NSLog(@"%zu",malloc_size((__bridge const void *)student));
}
return 0;
}
//打印结果为 16 16 16 16
-
Person类的内存占用
将OC
转化成C++
。
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _sex;
};
为什么class_getInstanceSize
返回的大小是16
在NSobject内存占用这个文章中讲到过NSObject
实际上里面只有一个isa
指针参数,占用8
个字节的内存,而sex
是int
类型占用4
个字节的内存,加起来一共是12
个字节,而class_getInstanceSize
方法返回的是实例对象占用的内存大小
,应该是12
个字节才对。呢这里为什么返回的是16
呢
-
内存补齐
返回的内存大小是成员变量中占用内存最大的呢个成员变量的倍数
而Person
类中占用内存最大的成员变量是isa
占用8
个字节的内存,根据内存补齐的原则应该返回的是8的倍数
,所以最少是16
-
class_getInstanceSize
的实现方法给到了明确的说法
uint32_t alignedInstanceSize() const {
return word_align(unalignedInstanceSize());
}
word_align
方法中调用了这么一个方法,align
是补齐的意思,也就是说他做内存补齐。而上面已经说到了内存补齐
的具体计算方法。所以这里返回的成员变量的内存大小是做了内存补齐后的大小,因此是16
-
Student类的内存占用
将OC
转化成C++
。
struct Student_IMPL {
struct Person_IMPL Person_IVARS;
int _age;
};
在上面已经说过了Person
类返回的内存大小是16
,Student
类中又新添加了一个成员变量age
,按理来说应该返回的是20
,然后内存对齐一下返回的应该是32
才对的。呢这里为什么返回16
了呢。
首先Person
类分配了16个内存空间,但是isa
和sex
属性只占用了12
个字节的内存空间,还剩下4
个字节的内存空间。刚好分配给age
属性使用,所以返回的结果就是16
而不是32
补充说明
@interface Student : NSObject
{
@public
int _age;
int _sex;
NSString *name;
}
如果像上面这样的话内存占用应该是多少呢。按照前面所说的东西来总结的话应该是24
。但是实际的返回确实32
。关于这个问题我有查询过源码的东西,但因为自己的技术水平有限在解析源码的时候走到一定的程度发现无法在往下去查看了。并没有找到完整的逻辑。但是我在网上查询了一下相关的资料。发现计算机中也存在着内存对齐的问题,也就是说返回的内存块的大小只能是16、32、64......
这样的