iOS小知识之获取内存大小的三种方式

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

1.1 sizeof

  • sizeof不是函数,而是一个操作符
  • 一般会传入数据类型,编译器在编译时期即可确定大小
  • sizeof得到的大小,即是该类型占用的空间大小

1.2 class_getInstanceSize

  • class_getInstanceSizeruntime提供的api
  • 作用:获取类的实例对象所占用的内存大小
  • 本质:获取实例对象中成员变量的内存大小
  • 采用8字节对齐,参照对象的属性大小

1.3 malloc_size

  • 作用:获取系统实际分配的内存大小
  • 采用16字节对齐,参照整个对象的大小
  • 实际分配的内存大小,必须是16的整数倍

具体案例分析 打开LGPerson.h文件,写入以下代码:

@interface LGPerson : NSObject
   
@property (nonatomic, copy) NSString *name; 
@property (nonatomic, copy) NSString *nickName; 
@property (nonatomic, assign) int age; 
@property (nonatomic, assign) long height; 

@end
复制代码

打开main.m文件,写入以下代码:

#import <Foundation/Foundation.h> 
#import "LGPerson.h" 
#import <objc/runtime.h> 
#import <malloc/malloc.h> 
int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
        LGPerson *person = [LGPerson alloc];
        NSLog(@"sizeof:%lu",sizeof(person)); 
        NSLog(@"class_getInstanceSize:%lu",class_getInstanceSize([LGPerson class]));
        NSLog(@"malloc_size:%lu",malloc_size((__bridge const void *)(person))); 
    }
    return 0; 
    
}

------------------------- 

//打印结果: 
sizeof:8 
class_getInstanceSize:40 
malloc_size:48
复制代码
  • sizeof为8,因为person对象,本质是指针地址,占8字节
  • class_getInstanceSize为40,LGPerson的成员变量大小为36字节8字节对齐后占40字节
  • malloc_size为48,系统分配的内存大小,经过16字节对齐后,占48字节

扩展

在LGPerson中,即是没有任何成员变量,class_getInstanceSize依然会占8字节,因为LGPerson继承自NSObject,默认存在isa成员变量

@interface NSObject <NSObject> {
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wobjc-interface-ivars" 
    Class isa OBJC_ISA_AVAILABILITY; 
#pragma clang diagnostic pop 
}
复制代码

isaClass类型,本质是objc_class类型的结构体指针,占8字节

typedef struct objc_class *Class;
复制代码

objc_class继承自最原始的objc_object结构体

struct objc_class : objc_object { 
    objc_class(const objc_class&) = delete;
    objc_class(objc_class&&) = delete;
    void operator=(const objc_class&) = delete; 
    void operator=(objc_class&&) = delete; 
    // Class ISA; 
    Class superclass; 
    cache_t cache; // formerly cache pointer and vtable 
    class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags 
    ... 
};
复制代码

找到objc_object结构体,只有一个成员变量isa

struct objc_object {
    Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
复制代码

所以,万物皆对象,万物皆有isa。

猜你喜欢

转载自juejin.im/post/7018002321858625544