【问题标题】:How to solve stringBuilder fragmentation?如何解决stringBuilder碎片?
【发布时间】:2011-05-14 10:45:57
【问题描述】:

我的 StringBuilders 中出现了一个很好的 SystemOutOfMemory 异常。这不是由于缺少内存,因此我认为这是内存碎片。

我有大约 200 个 StringBuiler 对象。所有这些都被定期重用(使用 strBldr.clear())。这似乎导致我的系统将内存碎片化得很糟糕。我该如何解决这个问题?

谢谢:)

编辑:

以下是一些数据:

输入和 stringBuilder 的最大记录大小:4 146 698。

平均重新启动 stringBuilders/秒:>120(可能 >>120)

输入@第一个错误的长度:16 972(字符串)

StringBuilder 长度@第一个错误:16

创建新 stringBuilder 的次数@第一个错误:~32500

内存使用总量@第一个错误 637 448K

【问题讨论】:

标签: c# .net stringbuilder memory-fragmentation


【解决方案1】:

我同意,很可能您不是内存不足而是碎片化了。

您必须熟悉碎片和大对象堆 (LOH)。

你没有提供任何细节,所以我只能给出一些非常广泛的建议:

  • 尝试估计您的字符串有多大,并将容量参数用于新的 SB
  • 四舍五入向上(真的)将这些大小设置为某个数字的倍数。这促进了重复使用。
  • 仅当您希望新内容的大小与旧内容几乎相同时才使用 Clear(),否则会导致您的死亡。

编辑

输入和 stringBuilder 的最大记录大小:4 146 698。

  • 确保不需要更大尺寸的中间体,然后
  • 创建所有 StringBuilders,如 sb1 = new StringBuilder(4200000);
  • 不要试图重复使用它们(太多/根本)
  • 不要将它们放置太久

【讨论】:

  • 当你说:“不要让它们太久”时,你的意思是我应该将 stringbuilder 设置为 null 吗?
  • 再一次,很难给出如此广泛的建议。将本地变量归零是没有意义的,将字段归零可能很有用。尽可能缩短他们的范围。
【解决方案2】:

您不应该像这样重复使用StringBuilder,只需根据需要创建一个新的。

当您在StringBuilder 上调用Clear 时,它不会释放它使用的所有内存,它只会将使用的大小重置为零。它仍然具有相同的大缓冲区,并且重复使用 StringBuilder 仅意味着缓冲区将尽可能大,并且永远不会缩小。

此外,保留 StringBuilder 对象以供重用意味着它们可以通过垃圾回收并继续到下一代堆。它们的收集频率较低,因此它们更有可能对内存碎片产生影响。

【讨论】:

    【解决方案3】:

    我最终做的是迁移到 x64。这解决了我的问题。

    有可能是我准确地分配了 x86 的整个内存空间,即使我没有全部使用它。迁移到 x64 肯定会解决这个问题。

    【讨论】:

      猜你喜欢
      • 2010-09-08
      • 1970-01-01
      • 2011-12-22
      • 2012-04-03
      • 2012-05-27
      • 2010-12-08
      • 2010-09-11
      • 2012-10-03
      • 1970-01-01
      相关资源
      最近更新 更多