type
status
date
slug
summary
tags
category
icon
password
为什么要内存对齐?
CPU 访问内存时,并不是逐个字节访问的,是以字长访问的。32 位 CPU 字长是 4 字节,64 位 CPU 字长是 8 字节。也就是 32 位 CPU 每次访问 4 字节,64 位 CPU 每次访问 8 字节
不进行内存对齐会有什么问题?
首先说明,不进行内存对齐并不会影响 Swift 语言 CPU 读取性能和速度。Swift 对内存对齐做了优化。但是手动内存对齐可以节省一些内存的同时,避免了 Swfit 进行自动补齐操作,所以 Swift 中的内存对齐是有意义的。
3
原理:
我们有一个 Person 模型
正常的 CPU 寻址:

Swift 优化过后的 CPU 寻址:

既然 Swift 对内存对齐进行了优化,我们还有必要手动的进行内存对齐吗?
有必要,我们看下方代码
我们已知 Bool 为 1 字节,Int 为 8 字节 (MemoryLayout.size(ofValue: true)可以验证,这里不做解释)
我们把 Bool 属性放在第一行,model 为 16 字节,我们把 Bool 属性放在最后一行,model 为 9 字节
Swift 为了优化寻址,会在不足字长时,补足字长,也就增大了内存消耗
上方案例,model size 为18,可以看出 bool 为 1 字节,int16 为 2 字节,但是还有 5 个字节没有补上,int 为 8 字节直接跟在 int16 的后边会造成两次读取,故系统补足了 5 字节,从 int 属性开始读。
最终 bool 和 int16 为 8 字节,int 为 8 字节, uint16 为 2 字节,加起来为 18字节。
尽管 Swift 已经为我们优化过了内存对齐,但是我们日常开发还是需要养成好习惯,把占用内存较大的属性写在上边,占用内存较小的属性写在下边,尽可能减少内存的占用
最后放上 Swift 中各类型字节数
class 的指针就是 isa 指针,指向类本身,占用 8 字节。
继承与 NSObject 的 class 只有 8 位,引用记数在 isa 中,未继承 NSObject 的 class 后边会多出 8 位的引用记数,Array 和 Dictionary 虽然为值类型,但是也是这样 7-15 位为引用记数的结构。
当强引用计数变成0后,对象会被摧毁(会走deinit方法),但该对象占用的内存不会释放,当强引用计数和弱引用计数都变成0后,这个对象所占用的内存才会被释放。
- 作者:NotionNext
- 链接:https://tangly1024.com/article/%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章