美文网首页
NSObject内存占用

NSObject内存占用

作者: 孙国立 | 来源:发表于2021-02-22 11:51 被阅读0次
1.测试用到的代码
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSObject *obj = [[NSObject alloc] init];
        NSLog(@"%zu",class_getInstanceSize([NSObject class]));
        NSLog(@"%zu",malloc_size((__bridge const void *)obj));
    }
    return 0;
}
//打印结果为8   16
2.OC转化成C/C++的实质
  • clang -rewrite-objc main.m -o main.cpp将oc转成c++的代码
  • main.cpp全局搜索NSObject,会找到如下图的一段代码
    NSObject转化成C的结构.png
  • 通过上图的代码结构可以发现NSObject转化成C++的代码结构后只有一个Class isa的这么一个指针参数。
内存占用的分析

最开始的代码打印的结果分别是816。具体来分析一下这两个结果是怎么出现的。

  • class_getInstanceSize结果为8的具体实现:
    首先去找一下objc的具体底层的实现,去objc官网地址下载最新的版本。全局搜索class_getInstanceSize方法会找到如下的代码。
size_t class_getInstanceSize(Class cls)
{
    if (!cls) return 0;
    return cls->alignedInstanceSize();
}
->然后跳转到"alignedInstanceSize()"方法的实现,代码如下
// Class's ivar size rounded up to a pointer-size boundary.
"这里有一行注释,说的是返回的是成员变量的内存大小"
    uint32_t alignedInstanceSize() const {
        return word_align(unalignedInstanceSize());
    }

通过查看底层的实现结合NSObejct转化成C++的代码可以很清楚的明白为何返回内存结果为8

  • malloc_size结果为16的具体原因
    首先学过C语言的都知道malloc方法是分配内存空间的操作。而[[NSObject alloc] init]就是做初始化操作,所以其中肯定存在分配内存空间的操作。所以我们找一下alloc的具体实现。
+ (id)alloc {
    return _objc_rootAlloc(self);
}
-> "_objc_rootAlloc()"方法的实现:

_objc_rootAlloc(Class cls)
{
    return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
-> "callAlloc"的具体实现
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)
{
#if __OBJC2__
    if (slowpath(checkNil && !cls)) return nil;
    if (fastpath(!cls->ISA()->hasCustomAWZ())) {
        return _objc_rootAllocWithZone(cls, nil);
    }
#endif
}

-> "在'callAlloc'方法中发现最终调用的是'_objc_rootAllocWithZone '方法,
然后再来查看一下"

_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone __unused)
{
    // allocWithZone under __OBJC2__ ignores the zone parameter
    return _class_createInstanceFromZone(cls, 0, nil,
                                         OBJECT_CONSTRUCT_CALL_BADALLOC);
}

-> "然后查看 '_class_createInstanceFromZone' 这个方法的实现"

_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone)
{
    void *bytes;
    size_t size;

    // Can't create something for nothing
    if (!cls) return nil;

    // Allocate and initialize
    size = cls->alignedInstanceSize() + extraBytes;

    // CF requires all objects be at least 16 bytes.
    if (size < 16) size = 16;

    if (zone) {
        bytes = malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
    } else {
        bytes = calloc(1, size);
    }

    return objc_constructInstance(cls, bytes);
}

最后在方法_class_createInstanceFromZone()方法中看到这么一行代码if (size < 16) size = 16;NSObject只有一个参数Class isa占用8个字节,小于16个字节,所以返回结果是16

特别说明一下

在查询源码的时候发现好多的代码分新版和旧版,有可能在新版中查询不到想要的信息,此时需要去查询旧版的信息才可能查询到一些想要的信息。也有可能是反过来查询。这个需要根据实际情况进行查询选择。

相关文章

  • NSObject内存占用

    1.测试用到的代码 2.OC转化成C/C++的实质 clang -rewrite-objc main.m -o m...

  • OC对象的本质

    1.一个NSObject对象占用多少内存 NSObject *obj = [[NSObject alloc] in...

  • 一个NSObject对象占用多少内存?

    今天来聊聊NSObject对象占用多少内存的话题。 一.什么是NSObject对象? NSObject *obj ...

  • OC对象本质

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

  • iOS-浅谈OC对象的本质

    目录 Objective-C的本质NSObject的底层实现一个NSObject对象的底层内存分布情况内存占用查看...

  • OC底层基础:面试题

    一、NSObject本质 一个NSObject对象占用多少内存(16)系统分配了16个字节给NSObject对象(...

  • iOS之OC对象占用多少内存

    NSObject对象占用多少内存空间 一个NSObject对象都会分配16byte的内存空间,通过源码可以知道: ...

  • IOS精选面试题(一)

    一个NSObject对象占用多少内存 系统分配了16个字节给NSObject对象 但是NSObject对象的内部只...

  • OC对象的本质

    一个NSObject对象占用多少内存? 由这个问题可以引出更多底层的东西。在这里要搞清楚NSObject对象在内存...

  • iOS Runtime面试题(NSObject)

    一个 NSObject 对象占用多少内存空间? 受限于内存分配的机制,一个 NSObject对象都会分配 16Bi...

网友评论

      本文标题:NSObject内存占用

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