一:
image.png
以上代码打断点在136行,转到汇编指令界面:
image.png
断点停在19行,看注释可知道0x5596(%rip)存的就是ptype这个全局变量,它的值来于18行rax,再继续往上推导,最终来自于12行的rax寄存器,11行是一个函数调用,所以可知12行的rax存的是11行函数调用的返回值。那我们打断点在11行,重新跑一下程序。
打印12行rax结果 rax = 0x0000000100006230 type metadata for Test_3.Person:
得知是Person的metadata(元)类型的地址
然后把断点打在17行,看15行注释,可得知17行rax存的是15行对Person实例化后堆空间的地址值(指针p存储的值),打印rax 值rax = 0x0000000102016ef0,输入命令 x/2xg 0x0000000102016ef0 查看这个这个堆空间里的值(打印可知Person实例占用16字节,所以这里打印16字节)
image.png可看到前8字节存的是0x0000000100006230 ,跟我们12行打印的Person的元类型地址值一样。
所以可以推敲出:Person实例的前八个字节存放的是该类的metadata的地址值(这是个比较小的值,可以推断在代码段,全局区,要验证的话可以再查看mach-o文件)
二:
接下来,我们给Person这个类添加两个Int类型存储属性age,score,它们的值分别为对应16进制的a,b。
image.png
通过打印我们得知这次Person实例占用32字节。仿照上面流程,我们打印出Peson实例的的内存为:
image.png
通过一的推导,我们知道前八位是Person的metadata的地址,第二个8位暂时不知。但第三,第四个8位的存储的值分别为10,11,就是我们的age,score的地址。
通过一,二,我们推导出Person实例的内存结构为如下
image.png
。现暂时可以得出总结:swift类结构布局为:前8字节为medata地址值,第二个8位现未知。从第三个8位开始存储它的存储属性。所以swift下类实例最少暂用16字节。
其实swift所有的基类都是隐藏的继承于_SwiftObject。从苹果开源的swift看到它的定义https://github.com/apple/swift/blob/master/stdlib/public/runtime/SwiftObject.h
网友评论