006 -class_rw_t & class_rw_ext-t & class_ro_t

讲这三个东西,要明白俩个概念:cleanMemory和dirtyMenory

cleanMemory:

加载后不会更改的内存,在内存紧张时,可以移除,需要时再从磁盘加载

比如:系统framework,app二进制文件,磁盘只读数据等。

dirtyMemory:

在进程运行时会发生更改的内存,只要程序运行,他就必须一直存在,比较昂贵。

2020之前的libObjc实现

只有class_rw_t和class_to_t





rw:可读可写:运行时生成,dirtyMemory

ro:只读编译期确定,cleanMemoty

Ps:这也解释了为什么运行时不能添加ivar,rw没有ivrlist,ro中的ivarlist编译期确定就不能再更改。

2020之后的libObjc实现

2020的wwdc上讲了新版libobjc对runtime的优化。增加了class_rw_ext_t: 按需分配

struct class_rw_ext_t {

    DECLARE_AUTHED_PTR_TEMPLATE(class_ro_t)

    class_ro_t_authed_ptr<const class_ro_t> ro;

    method_array_t methods;

    property_array_t properties;

    protocol_array_t protocols;

    char *demangledName;

    uint32_t version;

};


为什么这样做?

当没有class_rw_ext_t的时候,每个类在运行时都会拷贝一份methods,protocols,propertyies到class_rw_t,而实际上只有10%的类,通过category和runtime API动态修改了这些内容。其他90%的都和ro里的完全一致,这样就增加了不必要的dirtyMemory开销。

所以wwdc2020之后的版本把常用的内容保留在rw,可以按需分配的切分到rw_ext。这样就尽可能多直接使用cleanMemory中数据,减少dirtyMemory的开销,实现了内存优化。


补充:

·dirtyMemory在iOS系统中格外昂贵,因为iOS系统不支持交换空间,采用的是内存压缩技术,所以app的内存成本更高。

·尽量使用api访问底层数据结构,避免因为版本升级,底层数据结构变动导致的错误。

参考:

https://github.com/ramonChiu/wwdc2020_runtime_optimize

你可能感兴趣的:(006 -class_rw_t & class_rw_ext-t & class_ro_t)