空Swift字符串内存分配布局(堆栈/堆分配)

Sud*_*pta 10 string memory-management swift

在swift中,字符串是结构类型,因此值将存储在堆栈内存而不是堆中.

让我们说我们声明一个字符串:

let a = ""
let b = "o"
Run Code Online (Sandbox Code Playgroud)

这是一个空字符串,但是分配了一些内存.我需要知道给空字符串和字符串的内存有什么不同,让我们说计数1.


如果我们说: -

var str:String?
var str: String = ""
Run Code Online (Sandbox Code Playgroud)

通过绘图的内存布局的差异是我需要看到的.(堆栈/堆).

我试图在谷歌上找到这个,但我无法找到这个内存布局.

Ham*_*ish 9

String是一个非常复杂的野兽.它有许多不同的底层表示,包括:

  • 字符串文字,在二进制文件中存储为常量

  • 小字符串,最多可以在堆栈中内嵌15个UTF-8代码单元(至少在x86上)

  • "本机"字符串(即未桥接到Objective-C的字符串),存储在尾部分配的堆缓冲区中

  • 来自Obj-C的"外来"字符串,可以用标记指针或堆分配NSString对象表示

  • "共享"字符串,可以将Swift字符串文字表示为堆分配的Obj-C对象

如果你想深入了解细节,你可以从StringObject.swift开始,它有一堆注释解释一些布局细节.

要回答有关您提供的示例的问题:


let a = ""
Run Code Online (Sandbox Code Playgroud)

空字符串具有规范的小字符串表示形式,该表示形式内嵌存储在堆栈中.


let b = "o"
Run Code Online (Sandbox Code Playgroud)

字符串文字作为常量存储在二进制文件中.因此,不需要堆分配 - 指向二进制文件中字符串地址的指针就是所需要的.

但即使这不是一个常量字符串,例如它是由以下内容创建的:

let o = "O".lowercased()
Run Code Online (Sandbox Code Playgroud)

然后它仍然可以表示为一个小字符串,它被串联存储在堆栈中.


var str: String?
Run Code Online (Sandbox Code Playgroud)

String一个额外的居民(至少在x86上),这意味着String?可以共享相同的布局String.该值nil由额外的居民位模式之一表示.

但是,即使String没有额外的居民,将不需要额外的堆分配代表String?String-这将只需要在线存储的附加位.