OC底层原理02- alloc底层探索

274 阅读2分钟

前言

上一篇文章我们研究的alloc 我们的注意力转移到了内存大小 通过内存的大小得出一些字节对齐的算法 还有一些原理 但是我们的对象的大小 真正的大小是多少还不知道 我们继续探索

Xnip2021-06-08_21-31-55.jpg

按照上篇文章 如上图所示 按照8字节对齐规则应该是 8+8+4->24字节 实际是多少呢 我们来搞一下 跑起来 一顿断点 走一下 截图一波

Xnip2021-06-08_21-37-46.jpg

Xnip2021-06-08_21-38-20.jpg

Xnip2021-06-08_21-38-45.jpg

Xnip2021-06-08_21-39-01.jpg

Xnip2021-06-08_21-39-09.jpg

Xnip2021-06-08_21-40-59.jpg

Xnip2021-06-08_21-41-12.jpg

Xnip2021-06-08_21-42-01.jpg

Xnip2021-06-08_21-44-44.jpg

如上图所示

1.我们上篇文章有说到alloc流程第一步先调用+ (id)alloc这个方法 但是如上图 为什么第一步先调用 id objc_alloc(Class cls) 这个方法呢?Why

2.size得到的大小按之前理解应该是24 为啥是32呢 Why
带着这两点疑问 我们往下走

一.LLVM 优化alloc

通过查看LLVM代码 源码地址:apple/llvm-project

Xnip2021-06-08_23-00-53.jpg

查看上图

第一次alloc走的是 id objc_alloc(Class cls) 这个方法 添加标记

第二次alloc走的是 + (id)alloc

Xnip2021-06-08_22-56-09.jpg

查看上图

苹果真是太骚了 先hook 先走objc_alloc->alloc

alloc->objc_alloc-标记receiver标记完 objc_alloc->objc_msgSend alloc->objc_rootAlloc 这块后续更新

二.对象的内存的影响因素

影响内存的因素有哪些呢?我们来搞一搞 看下图

LGPerson添加一个name的属性 Xnip2021-06-08_23-25-47.jpg 我们打印看一下

Xnip2021-06-08_23-26-48.jpg

打印person的内存大小是16

我们在给LGPerson添加一个成员变量nickName

Xnip2021-06-08_23-27-03.jpg

我们打印看一下

Xnip2021-06-08_23-27-31.jpg

打印person的内存大小是24

我们给 LGPerson添加一个方法sayNB

Xnip2021-06-08_23-34-00.jpg

我们打印看一下 Xnip2021-06-08_23-27-31.jpg

总结: 对象的属性和成员变量会影响内存大小 方法影响不到内存大小

三.结构体内存对齐

类型占用字节数表格 Xnip2021-06-08_23-53-14.jpg

内存对齐的原则

1.数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在 32 位机为4字节,则要从4的整数倍地址开始存储。

2.结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

3.收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍.不足的要补齐。

Xnip2021-06-08_23-59-41.jpg

Xnip2021-06-08_23-59-51.jpg

打印结果对得上 如下图我们总节了一个结论就是 成员变量8字节对齐 对象内存16节对齐

Xnip2021-06-09_07-06-42.jpg

四.malloc源码引入

Xnip2021-06-09_06-47-13.jpg

Xnip2021-06-09_06-47-28.jpg

Xnip2021-06-09_06-49-35.jpg

Xnip2021-06-09_06-51-23.jpg

Xnip2021-06-09_07-25-52.jpg