« Traduction de code VB.NET <-> C# | Main | Checking the validity of an e-mail address »

Common garbage collection problems and how they are reflected in the views

Taken from http://msdn.microsoft.com/library/en-us/dnpag/html/scalenethowto13.asp

Common garbage collection problems and how they are reflected in the views

Programs that allocate too much

Sometimes the problem is very simple - your program allocates too much memory. This might not be obvious if the memory is short-lived - then the garbage collector cleans it up quickly, and your application simply runs slower than it needs to.

This section includes a simple demo with this type of problem, and will go through the views and see how the problem appears.

The source code for the demo application is as follows.

It is really simple - the inner loop builds a long string by repeatedly appending, and then the string is wrapped in an outer loop just so it runs long enough for reasonably accurate timing.

Running this program on a 2.2 GHz Pentium 4 box gives the following result.

C:\CLRProfiler>string_append.exe
Program ran for 1.563 seconds

This is not really slow, but could it be faster?

You can run this demo application under CLRProfiler and go through the views.

(...)

The total amount of memory allocated is almost 2 gigabytes. This means the program allocates over a gigabyte per second when it is not running under the profiler. That is actually quite a respectable performance by the garbage collector. What is allocated is almost entirely composed of strings - 99.86 percent. Everything else is negligible.

(...)

Not only are many strings allocated, but many of them are long strings. This is because every time you append to a string, the .NET Framework allocates a longer string and copies both components into it.

(...)

Almost all the memory in this example is allocated from two overloads of String::Concat().

(...)

Note the data that indicates "gc #6647", which means that this little program actually caused 6,647 garbage collections!

There are garbage collections happening all the time (almost every millisecond under the profiler, and even faster without it). And - as you already know - almost everything the program allocates is a string.

(...)

As you have probably known all along, the fix for this particular problem is very simple - use the StringBuilder class instead of String when building long strings.

If you adapted the source code of the demo application to do this, it would look like the following example.

This code looks a bit less elegant now, but is a lot faster. On the previously described computer, it prints the following:
C:\CLRProfiler>string_append.exe
Program ran for 0.156 seconds

Thus, it is about 10 times faster than the original - not bad for such a simple change.

(...)

The big thing to notice here is that the total amount of allocation dropped from 1.6 gigabytes to 21 megabytes. This is a factor of 80!

(...)

Recall that the total amount was about 30 megabytes before - now it is just 250 kilobytes.

(...)

Finally, the Time Line view reflects the smaller total amount of allocations as a smaller number of garbage collections (79 instead of 6647), as shown in the following screen shot.