讲这三个东西,要明白俩个概念:cleanMemory和dirtyMenory
cleanMemory:
加载后不会更改的内存,在内存紧张时,可以移除,需要时再从磁盘加载
比如:系统framework,app二进制文件,磁盘只读数据等。
dirtyMemory:
在进程运行时会发生更改的内存,只要程序运行,他就必须一直存在,比较昂贵。
2020之前的libObjc实现
只有class_rw_t和class_to_t
![](https://img.haomeiwen.com/i6491553/14f889a469337b89.png)
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的开销,实现了内存优化。
![](https://img.haomeiwen.com/i6491553/bbe39f744da659a4.png)
补充:
·dirtyMemory在iOS系统中格外昂贵,因为iOS系统不支持交换空间,采用的是内存压缩技术,所以app的内存成本更高。
·尽量使用api访问底层数据结构,避免因为版本升级,底层数据结构变动导致的错误。
参考:
https://github.com/ramonChiu/wwdc2020_runtime_optimize
网友评论