美文网首页
64位架构下实例对象占用内存

64位架构下实例对象占用内存

作者: 我才是臭吉吉 | 来源:发表于2019-09-27 06:57 被阅读0次

参考链接:

我们知道OC实例对象的指针占用的内存为8字节(isa指针,或者说是objc_class结构体指针)。

但是,实际上一个OC对象的内存占用为至少16字节

在OC对象alloc方法的源码中,可以看到:

static __attribute__((always_inline)) 
id
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, 
                              bool cxxConstruct = true, 
                              size_t *outAllocatedSize = nil)
{
    if (!cls) return nil;

    assert(cls->isRealized());

    // Read class's info bits all at once for performance
    bool hasCxxCtor = cls->hasCxxCtor();
    bool hasCxxDtor = cls->hasCxxDtor();
    bool fast = cls->canAllocNonpointer();

    size_t size = cls->instanceSize(extraBytes);
    if (outAllocatedSize) *outAllocatedSize = size;

    id obj;
    if (!zone  &&  fast) {
        obj = (id)calloc(1, size);
        if (!obj) return nil;
        obj->initInstanceIsa(cls, hasCxxDtor);
    } 
    else {
        if (zone) {
            obj = (id)malloc_zone_calloc ((malloc_zone_t *)zone, 1, size);
        } else {
            obj = (id)calloc(1, size);
        }
        if (!obj) return nil;

        // Use raw pointer isa on the assumption that they might be 
        // doing something weird with the zone or RR.
        obj->initIsa(cls);
    }

    if (cxxConstruct && hasCxxCtor) {
        obj = _objc_constructOrFree(obj, cls);
    }

    return obj;
}

其中,instanceSize函数的实现为:

size_t instanceSize(size_t extraBytes) {
     size_t size = alignedInstanceSize() + extraBytes;
      // CF requires all objects be at least 16bytes.
      if (size < 16) size = 16;
      return size; 
}

可以看出,在分配内存时,OC对象的最小内存占用为16字节

而通过查看内存分配可知,OC对象的内存是按照16字节进行对齐的

因此,在当类中存在其他属性时,在内存分配时,不足的需要按16字节进行补齐。

例如:

@interface TestClass : NSObject

@property (nonatomic, assign) NSInteger age;
@property (nonatomic, assign) int height;
@property (nonatomic, assign) int row;

@end


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        TestClass *obj = [TestClass new];
        obj.age = 4;
        obj.height = 5;
        obj.row = 6;
        
        NSLog(@"类的实例尺寸----%zd", class_getInstanceSize(obj.class));
        
        const void *objPtr = (__bridge const void *)obj;
        NSLog(@"类实例分配的空间====%zd", malloc_size(objPtr));
    }
    return 0;
}

输出为:

2019-09-12 11:23:08.682507+0800 AlgorithmLearning[30513:6166466] 类的实例尺寸----24
2019-09-12 11:23:08.682960+0800 AlgorithmLearning[30513:6166466] 类实例分配的空间====32

通过查看obj的内存分配可以看到(lldb的”x 地址“指令):

(lldb) x 0x000000010102be80
0x10102be80: 09 25 00 00 01 80 1d 00 05 00 00 00 06 00 00 00 .%..............
0x10102be90: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

可以看出,前8字节为objc_class指针,后面依次为4字节的height,4字节的row,之后是8字节的age。
在前16字节中,因为占用内存已满,因此,要开辟第二行来存储age,所以,实例的尺寸为 8 + 4 + 4 + 8 = 24 字节。但由于内存分配按照16字节对齐,因此第二行还要补齐缺失的8字节,因此obj实例实际分配的内存空间为 24 + 8 = 32字节。

相关文章

  • 01.OC实例对象的本质

    你知道NSObject实例对象占用了多少内存么?要回答这道题,我们要探索下OC实例对象的本质,而实例对象的本质其实...

  • 64位架构下实例对象占用内存

    参考链接:OC对象占用内存原理 (一文彻底搞懂) 我们知道OC实例对象的指针占用的内存为8字节(isa指针,或者说...

  • java 内存布局

    Java 内存的布局主要是统计Java对象占用内存的大小。 Java对象的内存布局:对象头(Header)、实例数...

  • iOS 实例对象占用内存

    1. NSObject的实例对象占用多少空间? 答: 16个字节;其中主要涉及到两个方法;class_getIns...

  • OC对象的分类

    1.instance对象(实例对象)通过类alloc出来的对象 是不同的对象,分别占用不同的内存, instanc...

  • iOS OC对象的本质

    实例对象 一个NSObject对象占用多少内存? 系统分配了16个字节给 NSObject 对象(通过 mallo...

  • Scala类和对象

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

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

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

  • 3.0 C++远征:构造函数

    6-1构造函数 1.内存分区 2.对象结构 对象在被实例化之前,并不占用堆中或栈中的内存空间。 实例化的三个car...

  • javascript 为什么要使用 prototype

    答案:节省内存占用 没有 prototype 会有什么问题? 考虑一下我们在 js 中如何创建类的实例对象?先定义...

网友评论

      本文标题:64位架构下实例对象占用内存

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