字符串生成器的内存分配.记忆中发生了什么?StringBuilder与String



可能是重复的,因为这个主题有很多问题,但我找不到我要找的东西。

我知道String是不可变的,StringBuilder是可变的。我理解这两个术语的本质。我想知道当我创建StringBuilder的实例时,内存中到底发生了什么。类似:

StringBuilder s = new StringBuilder();
  1. 内存中为s保留了多少空间
  2. 我可以像s[0] = 'a';一样使用它,所以我们可以称它为数组吗
  3. 如果s是基于索引的,这是否意味着字符存储在内存中的连续位置
  4. 如果3的答案是肯定的。那么,如果我们使用s.Append("abc");,而内存中没有足够的连续空间用于"abc",会发生什么呢?它会把s带到一个新的内存位置吗?就像每次我们把一些东西附加到string类型变量时string发生的情况一样

StringBuilder实际上是一条StringBuilders链(可以将它们看作是链接的内存块)。用户显然正在与单个StringBuilder交互,但事实远非如此。

每个StringBuilder使用底层char阵列,并且当容量耗尽时,新的StringBuilder将被添加到链中。

记住这一点,你的具体问题的答案是:

  1. 查看实现,了解StringBuilder的默认容量,以及它的底层数组。您还可以使用构造函数重载来指定它,以满足您的特定需求
  2. 是的,StringBuilder在引擎盖下使用了一个数组,但链中的每个构建器都有自己的数组
  3. 是和否。链中每个内部构建器的数组的内存是连续分配的,但不同的内存块不需要也很可能不会连续分配
  4. 当没有足够的空间时,将新的StringBuilder添加到链中,并在运行时认为合适的地方分配其相应的数组;典型地,新的构建器将至少使CCD_

显然,该系统允许动态调整大小,同时避免了与调整阵列大小和来回复制数据相关的成本。

StringBuilder允许分配非连续内存,以提供对单个连续字符串的感知。我相信它内部有一组指向字符串片段的指针,当你调用"ToString"时,这些指针会被重新组装——数组索引的处理只是数学的包装。当你.Append()时,它只会获取一块新内存,并将字符串片段放在其中,维护片段及其长度的索引列表

相关内容

最新更新