我有一个长度为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是全局变量
答案 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')作为变量的名称,你的生活和其他人的生活将得到改善。使用不同的命名约定(例如,以变量的小写字母开头)