002-内存对齐

前言

本文来探讨, 结构体对齐, 位域, 联合体对齐, 系统内存开辟, 内存对齐原则.

上一篇的坑

01.png

上一篇中留了一个大坑, 就是在汇编的时候objc_alloc这个符号其实在源码中是没有调用的. 由于_objc_rootAlloc和这个乍一看没在意, 感觉就是一个东西, 所以忽略了. 后面多参考参考其他人的方式专门写一篇, 遇到类似这种问题无从下手的问题, 怎么入手的解决的办法和逻辑.

因为这种问题的入手思维, 尝试不同的解决方式, 我觉得是非常重要的. 所以打算另起一篇

结构体对齐

先讨论没有自定义pack的情况, 自定义pack参数只能是 '1', '2', '4', '8', or '16'就是按照指定的pack参数进行对齐, 搞懂了没有pack的情况 ,有pack的自然懂。

结构体

结构体对齐的原则:
在没有定义 #pragma pack(value)的情况下, 原则如下:

  • 第一个成员的首地址为0.
  • 每个成员的首地址是自身大小的整数倍
  • 结构体的总大小,为其成员中所含最大类型的整数倍。
02.png

如上图所示, 每一个成员的起始地址都是自身大小的整数倍, 结构体的总大小是成员变量中最大的成员的整数倍.

结构体嵌套结构体

先上图:

03.png

联合体 && 结构体嵌套联合体

04.png

位域 && 结构体嵌套位域

  1. 位域(位段)结构的大小既取决于结构内部所有位域的总大小,也取决于该位域声明时的类型
  2. 当一个位域结构内部所有位域总大小小于该结构中位域声明时的类型中长度最大的类型长度
    时,该结构大小为该类型长度 (此处用用大小和长度区分自定义结构和C语言内置类型)
  3. 位域结构的大小总为该结构中存在的所有的位域在声明时所用的内置类型中长度最大的内置类型的长度的整数倍

继续上图:

05.png

结构体嵌套位域

06.png

总体来说, 位域联合体这种单片机什么的用的多, 正常了解一下即可. 知道怎么计算, 对内存有一个好的认识就行了.

内存对齐原则

上面的东西看懂了, OC的原则也是一样, 有内存优化, 不完全按照顺序排列, 对齐方式都是一致. 先看一下自定义类和原生的size区别:

07.png

08.png

上面两个图可以知道, 成员变量对一个类的实际大小有影响, 经过测试, 方法, 属性都没有影响. 但是@property会自动合成set, get, ivar所以属性也可以实际影响到内存大小. 有兴趣的可以@synthesize @dynamic, 里面还是有坑点的.

09.png
10.png

图9中对, age, c1, c2进行了优化, 都放在了同一个8字节中处理, 测试在加入两个char也会一同合并进去, 都是来自于OC对内存的优化.

系统内存开辟

先看下面的代码:

11.png

可以自己猜测一下结果先

sizeof

准确点说的话,sizeof并不是一个函数,当做是一个操作符,主要作用于编译时,作用的对象是数据类型。

sizeof 只会计算类型所占用的内存大小,不会关心具体的对象的内存布局;
sizeof(p), p是一个指向堆区Person空间的指针, 所以p的大小为8.

class_getInstanceSize

class_getInstanceSize为对象实际开辟的内存空间, 应该都知道是8字节对齐, 也说不上来为什么, 跟着objc的源码看一下, 还是通过汇编慢慢往里找也可以. 上一篇已经说过方案了, 查找流程都一致. 直接看objc:

//不多bb, 直接全局搜索, 直接找到, 往里面进
size_t class_getInstanceSize(Class cls)
{
    if (!cls) return 0;
    return cls->alignedInstanceSize();
}

uint32_t alignedInstanceSize() const {
        return word_align(unalignedInstanceSize());
    }

#ifdef __LP64__
#   define WORD_SHIFT 3UL
#   define WORD_MASK 7UL
#   define WORD_BITS 64
#else
#   define WORD_SHIFT 2UL
#   define WORD_MASK 3UL
#   define WORD_BITS 32
#endif

//核心就在这里, 上一篇也讲到过, 在32位中就是4字节对齐, 64位中就是8字节对齐,
//一个宏定义兼容了两种系统, 并且代码也不用改动, 多好.
static inline size_t word_align(size_t x) {
    return (x + WORD_MASK) & ~WORD_MASK;
}

malloc_size

实际调用的malloc_size, 点击进入查看:

12.png

进入objc源码查看也没有, 完全无从下手, 此时可以留意左上角的红线.

此时: 进入思考, 怎么找到目标实现, 是否开源, 一无所知.

  1. 直接谷歌oc中malloc源码在哪个文档里, 出来一堆, 相信你看得懂


    13.png
  1. 直接赋值粘贴方法谷歌搜索
14.png

可以看到apple 开源官方文档里面有, 假设我们什么都搜不到, 什么都不知道, 只能去stack overflow找寻一下, 如果malloc的任何信息都搜索不到, 那么只能靠自己钻研了, 尝试像别人请教请教也自己钻研一下.

  1. 继续进入libmalloc的库, github上有很多提供可编译的版本拉过来直接用.
    从上面的图可知有malloc.h, 直接malloc的实现搜索malloc.c:


    15.png

直接找到malloc.c了, 进入探索一下.

  1. 汇编
    16.png

2, 源码
17.png

从上面汇编可以看出, 是一直在调用 看一下find_registered_zone内部, 但是经过调试断点其实return的地方都断不到, 此时只能跟着汇编走流程了, 一步一步, 大概断言到了几个流程, 但是由于我对x86的指令集不熟悉, 电脑usb口坏了, 只能大致记录一下过程, 等电脑修好大致在走一遍.

//最后走入了malloc.c 652行    最后等同于malloc_zones[0];
1. lite_zone->malloc_zones->nano_size->_nano_vet_and_size_of_live
->_nano_block_inuse_p
'''

这些代码的注释大多都是虚拟地址分配的, 我看的大致的意思就是注册过的内存malloc_zones, 当前进来的替换掉0位置的数据, 然后把0中的size返回回去. 也有可能是我理解错误, 后面电脑修好了 我在验证一下.

总结

知识太多, 有效吸收理解, 并不需要浪费大量时间研究并不是很有意义的东西, 对我们普通开发者来说, 比如find_registered_zone这段代码, 大致的注释就是虚拟内存分配的一些东西, 需要搞懂虚拟内存分配的流程, 像这种的有兴趣可以直接去读深入理解计算机原理, 理解之后估计能找到那种互通的感觉.

跟上时代的步伐, 一步一步慢慢走..稳住我们能赢!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容