据我所知,String和StringBuilder对象都在下面分配了连续的内存。
我的程序运行了几天,在String对象中缓冲了几个输出。这有时会导致outofmemoryexception,我认为这是因为连续内存不可用。我的字符串大小可以达到100MB,并且我经常连接新的字符串,这会导致分配新的字符串对象。我可以通过使用Stringbuilder减少新的字符串对象创建,但这不能完全解决我的问题
是否有替代连续的字符串对象?
答案 0 :(得分:1)
rope data structure可能是一个选项,但我不知道.NET的任何现成实现。
您是否尝试过使用LinkedList of strings?或许您可以修改您的体系结构以在磁盘上读取和写入文件,而不是将所有内容保存在内存中。
答案 1 :(得分:1)
通过这么大,你的字符串被移动到Large Object Heap(LOH),你会有更大的碎片风险。
一些选择:
使用StringBuilder。您将不那么频繁地重新分配。并尝试预分配,例如new StringBuilder(100*1000*1000);
重新设计您的解决方案。必须有替代方法来保持这么大的字符串。例如,List<string>
,在(非常)必要时仅转换为1个单个字符串。
答案 2 :(得分:1)
请勿使用字符串。
字符串将为每个操作复制并分配一个新字符串。也就是说,如果你有一个50mb的字符串并添加一个字符,直到垃圾收集发生,你将有两个(aprox)50mb字符串。 然后,你添加另一个字符,你将有3 ....等等。
另一方面,正确使用StringBuilder,即使用“Append”不应该有100 mbs的任何问题。
另一个优化是使用您的估计大小
创建StringBuilderStringBuilder SB;
SB = new StringBuilder(capacity); //是容量建议的起始大小
使用stringBuider来保存你的大字符串,然后使用append。
HTH
答案 3 :(得分:0)
我不相信使用String或StringBuilder有任何解决方案。两者都需要连续的记忆。是否可以更改您的体系结构,以便将正在进行的数据保存到List,文件,数据库或为此目的而设计的其他结构中?
答案 4 :(得分:0)
首先,您应该检查为什么这样做,并查看是否还有其他可以为您提供相同价值的事情。
然后你有很多选择(取决于你需要的),从使用日志记录到编写一个将字符串收集到List中的简单类。
答案 5 :(得分:0)
您可以尝试将字符串保存到数据库,例如TextFile,SQL Server Express,MySQL,MS Access,..等。这样,如果您的服务器因任何原因而停机(停电,有人撞到UPS,雷雨等),您就不会丢失数据。它比RAM稍慢,但我认为权衡是值得的。
如果这不是一个选项 - 最明确地使用stringbuilder来添加字符串。