NSObject对象占用的内存大小分析

将Objective-C转换为C\C++代码

下面的命令可以将Objective-C代码转换为C\C++代码, 但是转换出来的代码仅供分析参考.

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o mainarm64.cpp

如果需要链接其他框架,使用-framework参数。比如-framework UIKit.

使用上面的命令可以窥探出NSObject的底层实现如下:

1
2
3
4
5
6
7
8
9
//头文件定义
@interface NSObject <NSObject> {
Class isa;
}

//转换为C++代码后
struct NSObject_IMPL {
Class isa; //64位系统中指针占8个字节
};

可见,Objective-C的面向对象是基于C\C++的结构体实现的.

NSObject实例对象的内存分配

导入 objc/runtime.h 后可以使用函数class_getInstanceSize获得NSObject实例对象的成员变量所占用的大小为8个字节(内存对齐后的大小).

class_getInstanceSize([NSObject class])

导入 malloc/malloc.h后可以使用函数malloc_size获得NSObject实例对象指针指向内存的大小为16个字节.

malloc_size((__bridge const void *)(obj))

通过以下路径追踪NSObject对象的内存分配过程:

  1. allocWithZone:
  2. _objc_rootAllocWithZone()
  3. class_createInstance()
  4. _class_createInstanceFromZone
  5. instanceSize()

其中instanceSize()函数返回要为NSObject实例对象分配的内存大小, 其实现如下:

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

可见NSObject实例对象占用的最小内存为16个字节.