在C#中使用Substring方法时抛出内存不足异常

时间:2010-11-24 10:16:17

标签: c# exception

我有一个长度为9700000(大约)的字符串(MyString)。和一个for循环来从这个String

获取子串

for(int i=0;i<MyString.Length;i+=1000)
  {
    String SStr=MyString.Substring(i,1000);
  }

在这个循环中,我正在设置像OutOfMemory Exception这样的异常。但是,如果我将MyString分配给临时字符串并在for循环中使用它(temporary string)而不是MyString,那么它的工作正常。 这是什么原因。它是如何存储在内存中的?

编辑:我也使用了StringBuilder

for(int i=0;i<MyStringBuilder.Length;i+=1000)
   {
    String SStr=MyStringBuilder.ToString().Substring(i,1000);
   }

但同样的事情正在发生。

编辑 MyString和MyStringBuilder是全局变量

2 个答案:

答案 0 :(得分:2)

我不确定这个循环是否会终止。

不应该读:

for(int i=0;i<800; i+= 1000 )
{
    String SStr=MyString.Substring(i,1000);
}

因此i正在增加。

您还需要更改上限(i <800)

或许您实际上要做的是:

for(int i=0;i<800; i++)
{
    String SStr=MyString.Substring( i * 1000 ,1000);
}

答案 1 :(得分:1)

看起来MyString可能是一个属性,它本身在每次调用时都会创建一个新字符串。

你的800个SubString调用将使用大约2MB的内存,这不太可能是问题,但是如果你对MyString的800个调用都分配了9.7MB字符串的新副本,那么这将是一个问题。

编辑:

回答这个问题是一个移动的目标,因为你不断改变它,但是你的新StringBuilder示例每次都在循环周围调用ToString,这将生成原始字符串的另一个副本 - 这将需要大约9700000 * 9700000/1000个字符的空间,虽然垃圾收集器可能来自并拯救你,但却是一项非常多的分配工作。

如果你避免使用类的名称(例如'StringBuilder')作为变量的名称,你的生活和其他人的生活将得到改善。使用不同的命名约定(例如,以变量的小写字母开头)