自定义类的内存占用

2021-02-22  本文已影响0人  孙国立

演示代码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
struct Student_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _age;
    int _sex;
};

代码块中有agesexNSObject_IMPL这三个属性。agesex的类型是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
struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _sex;
};

为什么class_getInstanceSize返回的大小是16
NSobject内存占用这个文章中讲到过NSObject实际上里面只有一个isa指针参数,占用8个字节的内存,而sexint类型占用4个字节的内存,加起来一共是12个字节,而class_getInstanceSize方法返回的是实例对象占用的内存大小,应该是12个字节才对。呢这里为什么返回的是16

uint32_t alignedInstanceSize() const {
        return word_align(unalignedInstanceSize());
    }

word_align方法中调用了这么一个方法,align是补齐的意思,也就是说他做内存补齐。而上面已经说到了内存补齐的具体计算方法。所以这里返回的成员变量的内存大小是做了内存补齐后的大小,因此是16

struct Student_IMPL {
    struct Person_IMPL Person_IVARS;
    int _age;
};

在上面已经说过了Person类返回的内存大小是16Student类中又新添加了一个成员变量age,按理来说应该返回的是20,然后内存对齐一下返回的应该是32才对的。呢这里为什么返回16了呢。
首先Person类分配了16个内存空间,但是isasex属性只占用了12个字节的内存空间,还剩下4个字节的内存空间。刚好分配给age属性使用,所以返回的结果就是16而不是32

补充说明
@interface Student : NSObject
{
    @public
    int _age;
    int _sex;
    NSString *name;
}

如果像上面这样的话内存占用应该是多少呢。按照前面所说的东西来总结的话应该是24。但是实际的返回确实32。关于这个问题我有查询过源码的东西,但因为自己的技术水平有限在解析源码的时候走到一定的程度发现无法在往下去查看了。并没有找到完整的逻辑。但是我在网上查询了一下相关的资料。发现计算机中也存在着内存对齐的问题,也就是说返回的内存块的大小只能是16、32、64......这样的

上一篇下一篇

猜你喜欢

热点阅读