StringBuillder.Tostring()抛出内存不足异常
本文关键字:内存不足 异常 Tostring StringBuillder | 更新日期: 2023-09-27 18:25:05
即使清除了字符串生成器对象,我也会出现内存不足异常。
我想将数据表转换为CSV,当我试图将其转换为字符串时,我会遇到异常。
代码如下:
int lineCount = 0;
const int capacity = 10000000;
StringBuilder csvBuilder = new StringBuilder(capacity);
if (dt != null && dt.Rows.Count > 0)
{
using (var sw = new StreamWriter(FileName, false))
{
foreach (DataRow dr in dt.Rows)
{
csvBuilder.AppendLine(String.Join(fileSeperator, dr.ItemArray));
lineCount++;
if (lineCount >= 100000)
{
sw.Write(csvBuilder.ToString());
csvBuilder.clear();
lineCount = 0;
}
}
sw.Write(csvBuilder.ToString());
csvBuilder.clear();
lineCount = 0;
}
}
即使在我清除了字符串生成器对象之后,我也会出现内存不足的异常。
是的,这看起来是合理的。你的记忆力并没有耗尽,但你的记忆力很差。SB将被放置在Larg Object堆上,LOH被收集但未被压实。清除StringBuilder没有帮助。
解决方案当然很简单:使用较小的缓冲区,或者根本不使用。
//const int capacity = 10000000;
const int capacity = 1000000; // depends on average linelength
//if (lineCount >= 100000)
if (lineCount >= 1000)
你似乎使用StringBuilder来缓冲I/O,你对此进行了全面的分析吗?FileStream将已经缓冲,当你想提供帮助时,你应该瞄准8-16kB的缓冲区。
您可以检查的长度
if (csvBuilder.Length >= 100000)
{
sw.Write(csvBuilder.ToString());
csvBuilder.clear();
lineCount = 0;
}
csvBuilder.AppendLine(String.Join(fileSeperator, dr.ItemArray));
lineCount++;