目录
查看int类型的内存分布
func memoryAnalyForInt() {
//查看变量地址
//view Memory of " "
//Debug - Debug WorkFlow - View Memory
var age:Int = 10
print(MemoryLayout.size(ofValue: age))//8
print(MemoryLayout.stride(ofValue: age))//8
print(MemoryLayout.alignment(ofValue: age))//8
print(Mems.ptr(ofVal: &age))//0x00007ffeefbff528
print(Mems.memStr(ofVal: &age))//0x000000000000000a
}
查看枚举类型的内存分布(原始值的内存分布)
func memoryAnalyForEnum(){
enum Season:String{
case Spring,Summer,Autumn,Winner
}
print(MemoryLayout<Season>.size) //1 实际占用
print(MemoryLayout<Season>.stride) //1 分配大小
print(MemoryLayout<Season>.alignment) //1 对齐参数
//00 00 00 00 00 00 00 00
var sum1 = Season.Spring
print(sum1.rawValue) //Spring
print(Mems.ptr(ofVal: &sum1)) //0x00007ffeefbff468
print(Mems.memStr(ofVal: &sum1))//0x00
//01 00 00 00 00 00 00 00
var sum2 = Season.Summer
print(Mems.ptr(ofVal: &sum2)) //0x00007ffeefbff460
print(Mems.memStr(ofVal: &sum2))//0x01
//02 00 00 00 00 00 00 00
var sum3 = Season.Autumn
print(Mems.ptr(ofVal: &sum3)) //0x00007ffeefbff458
print(Mems.memStr(ofVal: &sum3))//0x02
//03 00 00 00 00 00 00 00
var sum4 = Season.Winner
print(Mems.ptr(ofVal: &sum4)) //0x00007ffeefbff450
print(Mems.memStr(ofVal: &sum4))//0x03
}
查看枚举类型的内存分布(关联值的内存分布)
func memoryAnalyForEnum2(){
//关联值的内存分布
//1个字节存储成员值
//N个字节存储关联值(N取占用内存最大的关联值)
enum TestEnum {
case test1(Int,Int,Int)//24
case test2(Int,Int)//16
case test3(Int)//8
case test4(Bool)//1
case test5//
}
print(MemoryLayout<TestEnum>.size)//25
print(MemoryLayout<TestEnum>.stride)//32
print(MemoryLayout<TestEnum>.alignment)//8
var e = TestEnum.test1(1, 2, 3)
print(Mems.ptr(ofVal: &e))
print(Mems.memStr(ofVal: &e))
//0x00007ffeefbff450
//0x0000000000000001 0x0000000000000002 0x0000000000000003 0x0000000000000000
e = .test2(4, 5)
print(Mems.memStr(ofVal: &e))
//0x0000000000000004 0x0000000000000005 0x0000000000000000 0x0000000000000001
e = .test3(6)
print(Mems.memStr(ofVal: &e))
//0x0000000000000006 0x0000000000000000 0x0000000000000000 0x0000000000000002
e = .test4(true)
print(Mems.memStr(ofVal: &e))
//0x0000000000000001 0x0000000000000000 0x0000000000000000 0x0000000000000003
e = .test5
print(Mems.memStr(ofVal: &e))
//0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000004
}
特殊情况
func memoryAnalyForEnum3(){
//因为枚举只有一个值 所以不需要区分 实际占用的内存空间为0
enum Season2{
case spring
}
print(MemoryLayout<Season2>.size)//0
print(MemoryLayout<Season2>.stride)//1
print(MemoryLayout<Season2>.alignment)//1
var sum2 = Season2.spring
print(Mems.ptr(ofVal: &sum2))//0x0000000000000001
print(Mems.memStr(ofVal: &sum2))//空
//因为只有一个枚举值 所以不需要额外的一个字节来区分枚举的成员值 所以只占用8个字节 而不是9个字节
enum TestEnum2 {
case test1(Int)
}
print(MemoryLayout<TestEnum2>.size)//8
print(MemoryLayout<TestEnum2>.stride)//8
print(MemoryLayout<TestEnum2>.alignment)//8
var e2 = TestEnum2.test1(10)
print(Mems.ptr(ofVal: &e2))//0x00007ffeefbff528
print(Mems.memStr(ofVal: &e2))//0x000000000000000a
}
switch汇编分析
func memoryAnalyForSwich() {
enum TestEnum3 {
case test1(Int,Int,Int)
case test2(Int,Int)
case test3(Int)
case test4(Bool)
case test5
}
//0x100001e92 <+4914>: movq $0xa, 0x692b(%rip)
//0x100001e9d <+4925>: leaq 0x6924(%rip), %rdi
//0x100001ea4 <+4932>: movq $0x14, 0x6921(%rip)
//0x100001eaf <+4943>: movq $0x1e, 0x691e(%rip)
//0x100001eba <+4954>: movb $0x0, 0x691f(%rip)
//(lldb) register read rip
//rip = 0x0000000100001e92 LCClientDemo-commond`main + 4914 at main.swift:163:1
//0x100001e92 指令还未执行 此时寄存器 rip 存储的地址为 0x0000000100001e92
//在该条指令将要执行时 rip 存储的值会变为下条指令的地址 0x100001e9d
// 所以立即数$0xa 写入的内存地址为 0x100001e9d + 0x692b
let e3 = TestEnum3.test1(10, 20, 30)
switch e3 {
case let .test1(v1, v2, v3):
print("test1",v1,v2,v3)
case let .test2(v1, v2):
print("test2",v1,v2)
case let .test3(v1):
print("test3",v1)
case let .test4(v1):
print("test4",v1)
case .test5:
print("test5")
}
}
行者常至,为者常成!