要解决什么内存问题?你已经观察到的行为,但没有解释它是什么问题。
请注意,执行语句return result.ToString();
后立即StringBuilder
对象引用的对象有资格进行垃圾回收(假定这是对对象的唯一引用)。所以任何理论问题都应该是短暂的,可能会产生很少或根本没有实际影响的结果。换句话说:假设你建立了100个长度为N的字符串。这些字符串的名义开销是每个字符两个字节,所以内存中的开销是200 * N。在整个过程中,你正在构建这些字符串,额外的StringBuilder
对象的名义内存中的成本为N.是的,它可能不止一个这些对象可能一次存在,但只有当它不重要时。否则,.NET会垃圾收集旧的,为新的空间腾出空间。
因此,您的最终结果是额外的开销为1%,比您的问题暗示的内存翻倍要少很多StringBuilder
。这就是如果你只建立100个字符串。有效开销与您实际创建的字符串数量成反比,当然开销的重要性是直接与该相同数字成比例。换句话说,重要性越大,实际影响就越小。
更一般地说,你认为你会找到什么样的选择? StringBuilder
类是处理可变字符串的最佳方法,即提供一种从部分创建字符串或以其他方式编辑字符串(例如从中删除棋子,重新排列字符串等)的方法。也就是说,您可以实现自己的字符串编辑类,以专门的方式完成类似的效果。
但是不管你用什么来编辑字符串,如果你完成的时候你想有一个System.String
的实例,你必须在字符串中有两个数据副本:一个在可编辑版本,最后一个在System.String
对象中。你不能编辑一个System.String
对象(类型是不可变的),并且你不能神奇地将其他类型转换成System.String
的实例。
(虽然顺便说一句,我会注意到,在旧的实现StringBuilder
,从StringBuilder
缓冲实际上只是复制的参考到新System.String
对象。的无新副本除非在调用ToString()
之后的某个时间点创建了字符串数据,否则StringBuilder
对象再次被修改。StringBuilder
的当前实现不会这样做,它针对涉及较长字符串的场景进行了优化,避免了“缓冲区大小的两倍”重新分配成本总是要求最终ToString()
呼叫的数据副本的费用)。
现在,如果你能容忍使用字符串数据作为原始编辑对象(即StringBuilder
或其他自定义类)和数据从来没有转换到System.String
一个实例,那么这显然避免了二次办法数据副本。在这种方法中,你从不打扰ToString()
的呼叫。永远。
但是,除此之外,你似乎要求不可能,因为没有机制可用于获取现有的字符缓冲区,并强制使用该缓冲区作为其内部表示。即它在将任何其他数据结构(包括StringBuilder
)转换为System.String
的实例的过程中是固有的,即该数据的第二个副本将被创建。
如果不知道你想解决的问题,很难回答这个问题。但是,如果您的应用程序由于大字符串而使用了太多的内存,那么看起来应该不会使用字符串。流式方法可能会更好。 – Dirk 2015-04-02 08:18:29
是的,我们需要序列化它,并需要从另一侧读取。所以我们使用String。 – user3150546 2015-04-02 08:20:38
那么,如果你想使用字符串,那么你必须忍受后果。但是,如果使用StringBuilder连接已知(在编译时)的字符串数量,那么使用+ -operator可能会更好,因为编译器会将其转换为String.Concat,并且可能会避免为临时对象。 – Dirk 2015-04-02 08:29:59