Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

.NET

Optimizing Memory in .NET Applications


Too Many Objects

One of the most common problems is creating too many objects. Because allocating new memory with the .NET Framework is quite fast, it’s easy to forget that a single line of code could trigger a lot of allocations. The problem occurs when it comes time to collect these objects. Garbage collection involves a performance penalty, and collecting a large number of unnecessary objects exacerbates the problem.

This problem typically occurs when instructions generated from code create a class of objects known as temporary objects to perform their actions. Many .NET classes create temporary objects for their return values, for temporary strings and for associated classes such as enumerators that serve a necessary but short-lived purpose. An application developer can’t simply use any instruction to perform a particular action because that construct might produce undesirable side effects.

As a simple example, consider an exercise to concatenate two strings. It might seem simple to apply the "+" operator to perform this action. However, the "+" operator causes several new string objects to be created every time text is added to the string. Instead, using the System.Text.StringBuilder class often promotes faster string concatenation without creating new objects. This type of problem can be even worse in cases where a single instruction can create many temporary objects, all of which must be garbage-collected when their work is completed.

Object Leaks

Of course, even with the .NET garbage collection strategy, you can still have object leaks. An object leak occurs when a reference is made accidentally, or not removed appropriately, resulting in the object getting written to when the application is done with it. If this object is still in some way connected to a root structure, it won’t be collected, even if the application is done with that object. An example of such a leak is caching an object reference in a static member variable and forgetting to release it after the end of a request. The memory reference will remain until the application completes and the heap is returned to the operating system. This also leads to the issue of inappropriately long-lived objects. Because garbage collection is automatic, it’s easy to forget memory is still managed according to predefined rules. If an object is kept around long enough to be promoted to generation 2 of collection, it might never be collected until the application exits.

Why is this bad? Because the number of objects stored in the heap will likely keep growing while the application is running. This causes two problems. First, more heap memory extends the amount of time required to garbage collect, slowing down the application. Second, memory is not an infinite resource. If the application runs long enough, it will generate an out-of-memory error.

Too Many Object References

If you create an object that refers to many other objects, it can cause a couple of different problems. First, during all collections, it will force the garbage collector to follow all of the pointers between the objects, lengthening the time needed to complete the process. The results are particularly bad if this is a long-lived object structure, because the garbage collector goes through this process for every collection if the object has been modified.

Plus, large objects can cause problems. The .NET Framework keeps large objects (more than 20,000 bytes) in a separate large object heap, so that it can manage them separately from other objects. Large objects are never compacted because shifting 20,000-byte blocks of memory down in the heap would waste too much CPU time. Yet pointers between large objects and other objects can keep large objects alive longer than they need to be. And objects that are close to the 20,000-byte cutoff will still be allocated in the general-purpose heap, and compacting them will incur a significant performance hit.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.