美文网首页
自定义类的内存占用

自定义类的内存占用

作者: 孙国立 | 来源:发表于2021-02-22 11:51 被阅读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
  • OC代码转化成C++的代码
    将代码转化成C++的代码会找到如下的代码块
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
  • Person类的内存占用
    OC转化成C++
struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _sex;
};

为什么class_getInstanceSize返回的大小是16
NSobject内存占用这个文章中讲到过NSObject实际上里面只有一个isa指针参数,占用8个字节的内存,而sexint类型占用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类返回的内存大小是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......这样的

相关文章

  • 自定义类的内存占用

    演示代码1 默认为arm64。 OC代码转化成C++的代码将代码转化成C++的代码会找到如下的代码块 代码块中有a...

  • OC 对象的总结

    1 oc对象、类的本质是什么,OC对象的内存布局是什么样子的,一个NSObject对象占用多少内存,一个自定义类的...

  • 移动端测试经验-专项测试

    专项测试测什么? 资源类性能测试 Ø CPU占用 Ø 内存占用/内存泄漏 Ø 低资源环境表现 Ø 弱网络测试 速度...

  • GeekBand class4

    1.对于类继承的内存占用问题,derived类拥有base类的数据所占的内存空间,并同时拥有自己数据成员所占的内存...

  • 2020年自己遇到的面试题总结

    基础类 1、为什么会占用内存?什么时候释放?如何占用内存? 2、深拷贝 3、promise 事件代理几个状态 4、...

  • ios面试题

    1 NSobject本质是什么,占用多少内存 2 一个自定义对象占多少内存 对象实际 一个isa指针占用8个字节I...

  • C++对象模型探索

    2021.7.19 2.1 类对象所占用的空间 成员函数不占用类对象的内存空间,每个类只诞生 一个(跟着类走)一个...

  • Scala类和对象

    类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图...

  • Scala编程基础23:Scala类和对象

    类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图...

  • 轻量级自定义NumberPicker

    前言 一款自定义的WheelPicker控件,它的实现基于Android原生NumberPicker,有占用内存小...

网友评论

      本文标题:自定义类的内存占用

      本文链接:https://www.haomeiwen.com/subject/lzgaxltx.html