Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

c# - StringBuilder.ToString() throws OutOfMemoryException

I have a created a StringBuilder of length "132370292", when I try to get the string using the ToString() method it throws OutOfMemoryException.

StringBuilder SB = new StringBuilder();

for(int i =0; i<=5000; i++)
{
    SB.Append("Some Junk Data for testing. My Actual Data is created from different sources by Appending to the String Builder.");
}

try
{
    string str = SB.ToString(); // Throws OOM mostly
    Console.WriteLine("String Created Successfully");
}
catch(OutOfMemoryException ex)
{
    StreamWriter sw = new StreamWriter(@"c:memo.txt", true);
    sw.Write(SB.ToString()); //Always writes to the file without any error
    Console.WriteLine("Written to File Successfully");
}

What is the reason for the OOM while creating a new string and why it doesn't throw OOM while writing to a file?

Machine Details: 64-bit, Windows-7, 2GB RAM, .NET version 2.0

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

What is the reason for the OOM while creating a new string

Because you're running out of memory - or at least, the CLR can't allocate an object with the size you've requested. It's really that simple. If you want to avoid the errors, don't try to create strings that don't fit into memory. Note that even if you have a lot of memory, and even if you're running a 64-bit CLR, there are limits to the size of objects that can be created.

and why it doesn't throw OOM while writing to a file ?

Because you have more disk space than memory.

I'm pretty sure the code isn't exactly as you're describing though. This line would fail to compile:

sw.write(SB.ToString());

... because the method is Write rather than write. And if you're actually calling SB.ToString(), then that's just as likely to fail as str = SB.ToString().

It seems more likely that you're actually writing to the file in a streaming fashion, e.g.

using (var writer = File.CreateText(...))
{
    for (int i = 0; i < 5000; i++)
    {
        writer.Write(mytext);
    }
}

That way you never need to have huge amounts of text in memory - it just writes it to disk as it goes, possibly with some buffering, but not enough to cause memory issues.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...