简体   繁体   English

StringBuillder.Tostring()抛出内存不足异常

[英]StringBuillder.Tostring() throws out of memory Exception

I am getting out of memory exception even after i cleared the stringbuilder object. 即使清除了stringbuilder对象,我仍会出现内存不足异常。

I want to convert a data table to CSV, when i am trying to convert it into string i am getting the exception. 我想将数据表转换为CSV,当我尝试将其转换为字符串时却遇到异常。

The code is below: 代码如下:

        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;
                    }

            }

I am getting out of memory exception even after i cleared the stringbuilder object. 即使清除了stringbuilder对象,我仍会出现内存不足异常。

Yes, that looks plausible. 是的,这看起来很合理。 You're not running out of memory as such but you are suffering from fragmented memory. 您并没有像这样用尽内存,但是您正遭受内存碎片化的困扰。 The SB will be placed on the Larg Object heap and the LOH is collected but not compacted. SB将放置在Larg Object堆上,并且LOH已收集但未压缩。 Clearing the StringBuilder won't help. 清除StringBuilder将无济于事。

The solution is of course simple: use a smaller buffer, or non at all. 解决方案当然很简单:使用较小的缓冲区,或者根本不使用缓冲区。

//const int capacity = 10000000; 
  const int capacity = 1000000;    // depends on average linelength

//if (lineCount >= 100000)
  if (lineCount >= 1000)

You seem to use a StringBuilder to buffer I/O, did you profile that thoroughly? 您似乎在使用StringBuilder缓冲I / O,是否已对它进行了彻底的分析? The FileStream will already buffer, and when you want to help you should aim at a buffer from 8 - 16 kB. FileStream将已经缓冲,当您需要帮助时,您应该将缓冲范围定在8-16 kB。

you can check the length 你可以检查长度

if (csvBuilder.Length >= 100000)
{

    sw.Write(csvBuilder.ToString());
    csvBuilder.clear();
    lineCount = 0;
}
csvBuilder.AppendLine(String.Join(fileSeperator, dr.ItemArray));
lineCount++;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM