底层25:内存管理-内存布局/Tagged Pointer
2020-09-13 本文已影响0人
张无奈
iOS程序的内存布局
由低到高:代码段(__TEXT)、数据段(__DATA)、堆区、栈区、内核区。
Tagged Pointer
从64bit开始,iOS引入了Tagged Pointer技术,用于优化NSNumber、NSDate、NSString等小对象的存储。
在没有使用Tagged Pointer之前,NSNumber等对象需要动态分配内存,维护引用技术,NSNumber指针存储的是堆中NSNumber对象的地址值。
使用Tagged Pointer之后,NSNumber指针里面存储的数据变成了Tag+Data,也就是将数据直接存在指针中。
如何判断一个指针是否为Tagged Pointer?
iOS平台,最高有效位是1(64bit);Mac平台,最低有效位是1;
当指针不够存储数据时,才会使用动态分配内存的方式来存储数据
objc_msgSend能识别Tagged Pointer,比如NSNumber的intValue方法,直接从指针提取数据,节省了以前的调用开销。
第一段代码,字符串过长超出存储空间,会使用动态分配内存的方式来存储数据,调用setter方法中,可能存在多个线程同时访问,setter方法中需要先release掉旧数据,再接收新的数据,所以可能同时在release,导致name会被释放两次,产生坏内存访问崩溃。
但是换成第二段代码,没有崩,因为字符串“abc”是长度小,没有超过指针存储空间,属于Tagged Pointer, 直接从指针提取数据。
直接打印两个字符串也可以看出类型不一致