我们大多倾向于遵循上述最佳实践。

看一下 字符串与 StringBuilder

但 StringBuilder 可能会抛出 即使有足够的可用内存,也会出现 OutOfMemoryException. 。它抛出 OOM 异常,因为它需要“连续的内存块”。

一些链接供参考StringBuilder 内存不足异常

还有更多......

你们中有多少人面临或意识到这个问题,你们采取了什么措施来解决这个问题?

我有什么遗漏的吗?

附:我不知道这一点。

我已经重新表述了这个问题。

*** 同样的事情也适用于手动连接(我将验证这一点并更新SO)。另一件让我担心的事情是系统中有足够的内存。这就是我在这里提出这个问题的原因,以检查是否有人遇到过这个问题或者代码存在严重错误。

有帮助吗?

解决方案

创建的underyling串还需要一个连续的内存块,因为它被表示为字符数组(阵列需要连续的存储器)。如果StringBuilder的抛出OOM异常你woludn't能够建立底层没有它。

如果创建一个字符串导致OOM,有可能是在你的应用更严重的问题。

编辑响应于澄清:

有是的情况下,当手动级联成功建立一个字符串一个StringBuilder将失败的一小部分。手动拼接将使用以两个字符串结合而一个StringBuilder已分配内存不同algorithmn所需的精确长度。这是更积极,将可能分配比实际需要的字符串更多的内存。

使用一个StringBuilder也将导致由于串将存在于以System.String形式和StringBuilder的同时在短时间内所需要的存储器的临时增加一倍。

但是,如果一个方法是引起OOM,另一个则不然,它仍可能指向你的程序更严重的问题。

其他提示

如果StringBuilder的是要扔在你的特殊情况一个OutOfMemoryException,然后做手工字符串连接是不是一个更好的解决方案;它差很多。这正是StringBuilder的是应该使用的情况下(产生极,极长的字符串)。字符串的手动拼接这个大会采取多次与StringBuilder的字符串的建立将占用内存。

这是说,一个现代化的电脑上,如果你的字符串的运行的计算机进行连续的内存的设计是深深地,深深地缺陷。我无法想象你可能这样做会创建一个字符串那么大。

我们谈论的是多少内存?我不是在谈论系统中的可用内存或总内存,而是您要连接的字符串有多长?

内存溢出异常几乎总是关于代码的一个非常糟糕的迹象,即使它在内存实际耗尽之前很久就失败了,就像您由于连续内存不可用而经历的那样。

那时你应该真正重构代码。

例如,以下是解决该问题的多种方法:

  1. 不要一次在内存中保留尽可能多的数据,将其放在磁盘或其他东西上
  2. 将其分解,保留字符串/字符串生成器列表,并且仅在切换到新字符串之前将它们添加到一定长度,从而避免“连续内存”问题
  3. 重构算法以根本不在内存中建立千兆字节的数据

如果您运行的是如此接近你的内存限制,这是连关心,那么你或许应该考虑不同的体系结构或得到一个比较强大的机器。

如果你看看StringBuilder是如何实现的,你会看到,它实际上采用的是String来保存数据(String具有内部方法,这将允许StringBuilder到位修改)。

即。它们都使用相同的内存量。然而,由于StringBuilder将自动延伸的底层阵列并在需要时(但加倍容量)作为必要复制是最有可能的内存不足的错误的原因。但如其他人已经指出,两者的需要连续的存储器块,

好了,这个问题其实就是,你为什么需要那么长时间处理字符串的工作?如果你偶然发现这个问题,更可能你应该改变你的观念。

这个问题甚至影响的 System.String 的类,所以你还是块你输入列表<字符串> 的和并行处理数据,应该整体提高如果写入正确的性能。

我遇到了这个例外有sucessively不同stringbuilders(应该不会造成问题,因为他们是匿名函数内声明)建立了非常大的字符串,最后通过重用一个StringBuilder的,匿名函数的外部声明解决了这个问题。

我有我在那里追加字符串非常相似的经历,但忘了加上的String.Format。因此:

myStringBuilder.Append("1,""{0}""", someVeryLargeIntVariable)

应该是:

myStringBuilder.Append(String.Format("1,""{0}""", someVeryLargeIntVariable))

请注意,这是失败的我vb.net代码。我复制的类似的测试,在c#与:

myStringBuilder.Append('a', 1564544656);

VS

myStringBuilder.Append(string.Format("1,\"{0}\"", 1564544656));

但在我的情况下,vb.net让我陷入困境B / C的隐式转换的(我不平行的确切的在C#中同样的问题)。

我希望可以帮助别人。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top