Swift: sizeof与MemoryLayout

22 篇文章 0 订阅

C语言中,可能会经常与sizeof打交道,用来计算数据占用内存大小。在Csizeof即可以作用于类型也可以作用于某个实际的变量,并返回其在内存中的尺寸size_t

Swift 3以前,也有sizeof,不过与C中的运算符不同,它经过了一层包装,变成了一个只接受类型的方法,而接受具体值的则为另一个方法: sizeofValue

1
2
func <T>(_: T.Type) -> Int
func sizeofValue<T>(_: T) -> Int

不过sizeofValue接受的虽然是具体值,但是返回的是这个值的实际大小,而不是其内容的大小。所以与C中用sizeof拿来计算数组内容在内存中占据的尺寸不一样:

1
2
3
4
5
6
char bytes[] = {1, 2, 3};
sizeof(bytes);          // 3

int bytes[] = {1, 2, 3};
sizeof(bytes);          // 12
1
2
3
// Swift
let bytes = [1, 2, 3]
sizeofValue(bytes)      // 8: 64位系统一个引用的长度

MemoryLayout

Swift 3sizeofsizeofValue相关的被另一个新的枚举所替代,那就是MemoryLayout

基本使用方法

1
2
3
let a = 10
MemoryLayout<Int>.size              // 8
MemoryLayout.size(ofValue: a)       // 8

属性方法介绍

MemoryLayout有3个非常有用的属性及3个对应的Value方法,返回值都为Int类型。

size

实例使用size(ofValue: T)

T占用连续内存的大小,单位是字节。类型的大小不包括任何动态分配或不合适的存储,当T是类类型时,MemoryLayout<T>.size是相同的,不论T中存储属性有多少。当使用unsafe pointerT的多个实例分配内存时,使用多个该类型的stride而不是其size,这个涉及到内存对齐的问题,详见stride

stride

实例使用stride(ofValue: T)

当存储在连续存储器或Array<T>中时,从T的任意一个实例开始到下一个实例开始所占用的连续内存字节大小。

示例:

 

这是一个数组,里面有四个T类型元素,每个T元素的大小为size个字节,但是因为内存对齐的限制,每个T类型元素实际消耗的内存空间为stride个字节,stride - size个字节则为每个元素因为内存对齐而浪费的内存空间。

alignment

实例使用alignment(ofValue: T)

T的默认内存对齐方式,单位为字节。许多计算机系统对基本数据类型的合法地址做出了一些限制,要求某种数据类型对象的地址必须是某个值K(通常是 2、4或者8)的倍数。这种对齐限制简化了形成处理器和内存系统之间接口的硬件设计。对齐原则是任何K字节的基本对象的地址必须是K的倍数。

MemoryLayout.alignment就代表着数据类型T的内存对齐原则。而且在64位系统下,最大的内存对齐原则是8字节。

基本数据类型的MemoryLayout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 值类型
MemoryLayout<Int>.size                                      // 8
MemoryLayout<Int>.stride                                    // 8
MemoryLayout<Int>.alignment                                 // 8

MemoryLayout<String>.size                                   // 24
MemoryLayout<String>.stride                                 // 24
MemoryLayout<String>.alignment                              // 8

// 引用类型 T
MemoryLayout<T>.size                                        // 8
MemoryLayout<T>.stride                                      // 8
MemoryLayout<T>.alignment                                   // 8

// 指针类型
MemoryLayout<unsafeMutablePointer<T>>.size                  // 8
MemoryLayout<unsafeMutablePointer<T>>.stride                // 8
MemoryLayout<unsafeMutablePointer<T>>.alignment             // 8

MemoryLayout<unsafeMutableBufferPointer<T>>.size            // 16
MemoryLayout<unsafeMutableBufferPointer<T>>.stride          // 16
MemoryLayout<unsafeMutableBufferPointer<T>>.alignment       // 16

注意

以上所有都在64位系统中得到

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值