【问题标题】:StringBuilder growing over 85k and moving to LOH? [duplicate]StringBuilder 增长超过 85k 并转移到 LOH? [复制]
【发布时间】:2011-10-03 20:15:42
【问题描述】:

可能重复:
How does StringBuilder's capacity change?

假设一个 StringBuilder 被分配,然后它增长到超过 85k,它会被转移到大对象堆吗?

【问题讨论】:

    标签: .net clr large-object-heap


    【解决方案1】:

    StringBuilder 不会“增长”。

    在 4.0 之前的 SB 中,它只是分配了一个更大的新缓冲区并将内容从旧缓冲区复制到新缓冲区。所以最后是的,内部缓冲区被移到了 LOH。 SB 对象不是,因为它非常小(为了简单起见,它可能只是对缓冲区的引用和缓冲区中字符串的长度。它有点复杂,因为它在之后实现了写时复制使用ToString 方法。因此ToString 方法将缓冲区设为只读并将其作为字符串返回,任何其他对SB 的写入都会复制缓冲区)。

    在 4.0 中,SB 使用类似缓冲区链表(称为“绳索”)之类的东西,它们总是足够小而不会进入 LOH。

    【讨论】:

    • "总是小到不能去 LOH。"即使我Append 一个大小为兆字节的字符串也是如此吗?
    • @Jim 你是对的。 Append 将添加 0 个或 1 个块,因此添加的块将与需要一样大。
    【解决方案2】:

    StringBuilder 本身不会在 LOH 上分配,但它的内部字符串缓冲区会分配。分配器对哪些对象正在分配其数据一无所知。它只知道大于某个最大大小的分配将进入 LOH。

    【讨论】:

    • 这适用于 .NET 4.0 之前的版本。从版本 4 开始,使用了另一种策略,将内部缓冲区从多个缓冲区串在一起,避免将内部缓冲区移动到 LOH。
    • @driis:谢谢。我得去看看StringBuilder 来源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 2012-09-30
    • 1970-01-01
    • 2021-12-29
    • 2021-05-27
    相关资源
    最近更新 更多