Swift学习

Swift 中的内存分配情况与优化思路

2020-01-11  本文已影响0人  我是熊大啊

Allocation 内存分配

内存分配可以分为堆区栈区,在栈的内存分配速度要高于堆,结构体和类在堆栈分配是不同的。

1.Stack

基本数据类型和结构体默认在栈区,栈区内存是连续的,通过出栈入栈进行分配和销毁,速度很快,高于堆区。

2.Heap

高级的数据结构,比如类,分配在堆区。初始化时查找没有使用的内存块,销毁时再从内存块中清除。因为堆区可能存在多线程的操作问题,为了保证线程安全,需要进行加锁操作,因此也是一种性能消耗。
初始化了一个Class类型,在栈区分配一块内存,但是和结构体直接在栈内存储数值不同,我们只在栈区存储了对象的指针,指针指向的对象的内存是分配在堆区的。

内存分配总结:

从初始化角度,Class相比Struct需要在堆区分配内存,进行内存管理,使用了指针,有更强大的特性,但是性能较低。

优化方式:

对于频繁操作(比如通信软件的内容气泡展示),尽量使用Struct替代Class,因为栈内存分配更快,更安全,操作更快。

Reference counting 引用计数

Swift通过引用计数管理堆对象内存,当引用计数为0时,Swift确认没有对象再引用该内存,所以将内存释放。

对于引用计数的管理是一个非常高频的间接操作,并且需要考虑线程安全,使得引用计数的操作需要较高的性能消耗。

对于基本数据类型的Struct来说,没有堆内存分配和引用计数的管理,性能更高更安全,但是对于复杂的结构体

引用计数总结

Class在堆区分配内存,需要使用引用计数器进行内存管理。

基本类型的Struct在栈区分配内存,无引用计数管理。

包含强类型的Struct通过指针管理在堆区的属性,对结构体的拷贝会创建新的栈内存,创建多份引用的指针,Class只会有一份。

优化方式

在使用结构体时:
通过使用精确类型,例如UUID替代String(UUID字节长度固定128字节,而不是String任意长度),这样就可以进行内存内联,在栈内存储UUID,我们知道,栈内存管理更快更安全,并且不需要引用计数。

Enum替代String,在栈内管理内存,无引用计数,并且从语法上对于开发者更友好。

上一篇下一篇

猜你喜欢

热点阅读