Showing posts with label Performance. Show all posts
Showing posts with label Performance. Show all posts

Wednesday, 4 September 2013

ASP.NET Web Application Performance Improvement


In this article i will be explaining some of quick, easy and must use Asp.net Website Performance Improvement tips.
Asp.net Performance Improvement checklist is divided into 4 broad categories


  1. Identifying which part of asp.net web application requires optimization.
  2. Optimizing Asp.net web project to improve website performance
  3. Tips for writing code in order to enhance performance.
  4. Database Optimization to improve performance (I will be explaining for SQL Server but same tips will also apply to MySQL, Oracle or any other DB by changing syntactical meaning respectively.)
I will be discussing each of asp.net performance improvement categories in detail.

Identifying which part of asp.net web application requires optimization.

It is very important to identify which part of your application requires more attention in order to improve website performance.  

1 Using VS.Net 2010 Profiler
2 Tracing asp.net web application
3 Extension (Firefox Firebug, YSlow, Google Chrome Speed Tracer, IE9 Developer Tools)
4 Monitoring tools like fiddler will also be helpful.


Optimizing Asp.net web project to improve website performance.

In order to improve asp.net web page performance most important thing we should consider is
  • Reduce asp.net page size - By reducing page size page it will get download quickly and thus load quickly on user's browser.  It will also reduce bandwidth consumption of your website.  
  • Reduce number of HTTP request -  It is very important to reduce number of HTTP requests on your server, it will help in reducing the server load and allowing more visitors to access your website.
  • Avoid round trip to server.

In order to reduce asp.net page size.

1) Avoid viewstate - viewstate is used to persist data of web page on page postback.  This increase page size.  I always prefer to turn off viewstate at page level and only turn on viewstate to specific control whose data i need to persist over page postback.  

You can do so by <%@ Page  EnableViewState="false" %>

Situation in which you must avoid viewstate.
  • Only page which take user input or control whose values you want to persist on page postback will require viewstate.  Example: If user press submit button and if there are error on page we should persist user input, so in that case we should make EnableViewState="true" for those control or may be at page level.
  • Display pages or asp.net page which will not require page postback.  Example: Page on which you are displaying customers information in datagrid, doesn't require viewstate so in this situation you can turn of viewstate.
2) Use div instead of table. - Make use of div and css to replace table.  Combination of div and css is much more faster than table.

3) Avoid big name for asp.net server control and CSS class tag - Do not give big name for ID field of asp.net server control,  specially to ContentPlaceHolder  asp.net server control in master page.  ContentPlaceHolder ID name is appended to each and every asp.net server control inside child page, so if you choose a big name for your asp.net server control it will increase html file size.

Similarly if you choose a big name for CSS class tag, it will have long name on every instance you make use of that class tag and in return it increase html size.

For this reason, I prefer to choose very short name for any controls or css tag definition.
Example: <asp:ContentPlaceHolder ID="CC" runat="server">

4) Remove unnecessary white space (Compress generated HTML Size)
  • Remove white spaces between tags and lines of html render by asp.net page.  In order to remove white space dynamically on all page, you should put "render" method inside master page class file.
  • Remove unused tags from CSS file and also remove unused script from Javascript file.
  • Remove white spaces from CSS file while deploying to production server.  Remember, Comments and whitespace inside your CSS and Javascript file are not needed for execution; Removing them will speed up css rendering time and script execution times.  You can add this step to your deployment checklist. You can take advantage of online compress css tool and online javascript compress tool.

5) Make use of JQuery instead of Ajax Control toolkit.  
I have observed that JQuery can do the task with less code and light weight, while Ajax control toolkit is bulkier and increase page size.  Find more on JQuery vs Ajax control toolkit.



Reduce number of HTTP request
With help of Firebug, Firefox extension, you can find out how many resource request was made by your asp.net web page.  It is very important to reduce number of HTTP requests on your server, it will help in reducing the server load and allowing more visitors to access your website.

1) Make minimum use of Images.  Images are good for UI but can increase size of web page and also results in too many http request.

2) Combine multiple db request into single db request.  Find more details on How to avoid multiple database request to improve performance. 

3) Combine 2 or more css file into 1 file, since most of modern browser do cache css file, it will only take little more time for 1st request, all sub subsequent request will be super fast.  Combining multiple css file into 1 will reduce number of http request.

4) Combine 2 or more javascript file into 1 file, since most of modern browser do cache javascript file, it will only take little more time for 1st request, all sub subsequent request will be super fast.  Combining multiple javascript file into 1 will reduce number of http request.

5) Special tips if your web application is using JQuery
    • Try to use Jquery from CDN (Content distribution network) link for google CDN http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
    • While adding JQuery try using min version (Example: jquery-1.6.2.min.js), which is less file size, since space and line break are removed from that.  This will help in faster loading of file and also improves performance of web application.
    • Avoid too many third party jquery controls rather make use of JQuery UI, which supports too many control within one js file.


Avoid round trip to server
In order to give user a lightning fast effect, it is important that you avoid round trip to server.  You can use:
  • Caching
  • JQuery Ajax

Tips for writing code in order to enhance performance.

1 VS.Net 2010 Code Analysis


Database Optimizing tips to improve website performance.
1. Thumb rule decrease as many joins as possible.  It will be very helpful in improving search query performance.
2. In order to avoid too many joins, make optimal use of "xml datatype".  That will help you to reduce needs of number of tables for small data structure, also be helpful in storing complex data-type.  (In summary, I am in love of xml datatype, If you know correct way to use that, you can optimize performance.)
3 Check out DB Optimization tricks
4 Use PL\SQL Programming instead of making too many DB Request.
One of the most resource efficient and performance improvement technique is to make use of PL\SQL Programming inside stored procedure to avoid round trip.  But be careful with this technique if you don't know how to use it efficiently, it may adversely affect performance.
Example: To Improve Performance through


Finally i want to say it is also important to check your asp.net web application architecture.  Try to identify what all bad architectural design was taken in past and how to rectify those in order to improve performance of your web application.  Its very important to design architecture of web application nicely.  I understand that it is not always possible to design things right at first point, but it is continuous improvement process, you should always keep on identifying things and correct it asap.  Hope my checklist had helped you too.
Please note: I have been writing this article since long and I am still in process of improving this article on regular basis.  Please share your suggestions and comments here so that it will help everybody to improve their website performance.  At present most of performance improvement topics here are purely related to asp.net web forms, but i will be going to make a list of asp.net mvc specific performance improvement checklist in my future article.  Thank you. :)

The following are a few points that can make a site scalable and reliable; but which may initially slow down development. I believe that overall, when maintenance and future changes are taken into account, total development time would be reduced.

1. Minimize HTTP based Requestss

Problem 1: Serving images - no matter if they are of less than 1 KB - as separate web resources, cause separate web requests to the server, which impact performance.
Solutions:
  • Use Image Maps to merge up images, though image Maps could only merge up those images which are in sequence, like navigation images, so it depends upon your web site/page design.
  • Use Inline images. Inline images could increase your HTML page size but would cause fewer requests to the server.
  • CSS Sprites can also be used to merge up images and setting their position and backgrounds.
Problem 2: Using CSS is very good practice but serving stylesheets as separate resources, thus causing separate requests, should be considered very carefully.
Solutions:
  • Try your best to combine all your CSS based classes into a single .css file as lot of .css files will cause a large amount of requests, regardless of the file sizes.
  • .css files are normally cached by browsers, so a single and heavy .css file doesn’t cause a long wait on each page request.
  • Inline .css classes could make HTML heavy, so again: go ahead with a single.css file.
Problem 3: JavaScript is an awesome scripting language which can be quite powerful to play with. Nonetheless, it should be used carefully not only for request size issues; but also because it can have a way of causing unpredictable performance issues.
Solution: Inline JavaScript could make the HTML page heavy, so it’s preferred to serve separate .js files or a single JavaScript file to keep all JavaScript-based scripts in a single place.
JavaScript files also get cached automatically by browsers, so they usually aren’t requested each time the page is loaded by the browsers.

2. HTTP Compression

HTTP Compression is used to compress contents from the web server. HTTP requests and responses could be compressed, which can result in great performance gains. Through HTTP compression, the size of the payload can be reduced by about 50%, which is great. Isn’t it?
HTTP Compression is now widely supported by browsers and web servers.
If HTTP compression is enabled on the web server, and if the request header includes an Accept-Encoding: gzip, deflate header, the browser supports gzip and deflate compression mechanisms, so the response can be compressed in any of the given formats by the web server in order to reduce the payload size. This leads to an increase in performance. Latter that compressed response is decompressed by the browser and rendered normally.
Following are very good links which detail HTTP Compression and their implementations:
  • Click here to get detailed knowledge on HTTP compression.
  • Click here to learn how to enable HTTP compression in IIS.

3. Correct Formatted Images at the Right Place

Problem: Normally designers use JPG or GIF formats quite randomly and ignore some other good formats to compress images.
Solution: Correct format should be used for right purpose like
  • If you have to place a background image, some large image or a screenshot then the suggested format is JPG/JPEG.
  • If you have to use small graphics like button images, header images, footer images, navigation bar images or clip arts, then the suggested format is PNG.
  • If an image is not required to be in high or true colors and 256 colors are enough, then GIF is preferred.

4. Compress CSS, JavaScript and Images

CSS files (.css), images and JavaScript (.js) files can be compressed, as normally .css and .js files contain unnecessary spaces, comments, unnecessary code and such other things. A number of high quality (and free) utilities are available to help you pre-compress your files.
Following are a few good links for such utilities:
  • Compress PNG images by clicking here
  • Compress JPG images by clicking here
  • Compress .CSS files by clicking here and here and here
  • Compress .Js files by clicking here and here and here
I have used these utilities and seen compression results of about 50% in file size reduction after using such loss-less compression, so I recommend them.

5. CSS at Top

The recommended approach is to put CSS links on top of the web page, as it makes the page render progressively efficient. Since users want to see the contents of a page whilst it’s loading rather than white spaces, contents/formats should be given on top. HTML Specifications clearly say to declare style sheets in the head section of a web page.

6. Javascript at Bottom

When scripts are defined on top of the page they can take unnecessary time to load; they don’t show the contents that users are expecting after making any request to an HTTP web server. It's better to display a the HTML contents of a page, then load any scripting code (when possible, of course).
Preferably use/link up JavaScript-based scripts at the bottom of a web page. Alternatively you can use the defer attribute, which runs the script at the end of page loading, but that is not the preferable approach as it is not browser independent. For example, Firefox doesn’t support it and could mess up with document.write, so only use it once you fully understand the implications.

7. Content Delivery Network: (CDN)

When a browser makes a request to any web page – that is, he types a URL/URI of any web page or web site, a request goes through many hops (routers and computers) and then finally reaches its final destination. This happens both for requests and responses. This operation affects performance and can severely effect load time.
A Content Delivery Network implies a collection of computers, distributed all over the world, which deliver data (contents). Through a CDN you can have your website data on multiple servers distributed in different locations around the world. Distribute web application data in different places around the world so request can be served from the nearest location and save time (which means performance and money as well).

8. Ajax

Problemm: Ajax is being increasingly used to improve usability, but oftentimes in a way which increases overall server load.
Solutions:
Preferably use the GET method for Ajax based Requests, because if you use POST method then the request header would be sent first, followed by the data, which basically splits the request in two steps. A single-step request can be achieved with GET if a cookie is not too long and the URL is not larger than 2k.
  • When using ASP.NET AJAX and the UpdatePanel control for partial page rendering, use the maximum number of update panels to update small chunks of page, but use them wisely. Don’t set the Update property to Always unless needed. Instead, set the update mode to Conditional, otherwise all the partial chunks would be sent together after each asynchronous postback.
  • Ajax based requests can also be cached when using the GET method. If the URL is the same, then cached data can be used from the client, and a round trip to the server can be avoided.

9. Ajax vs. Callback

Problem: Ajax is a great solution for asynchronous communication between client (web browser) and HTTP servers, but one solution can't be applied to every problem. This means that Ajax is great mechanism for sending requests to the server without making a full page postback, but what if you need to send a request to the server and don’t even need partial rendering?
Solution: best solution is Callback.
For example, if you need to check whether a user exists or not, or if a user has forgotten his/her password and you just need to send a request to the server to check if user name exist, there is no need for client-side render - just a server side operation.
Following are a couple of great links which explain callbacks: Please click here and here.

10. Reduce Cookie size

Cookies are stored on the client side to keep information about users (authentication and personalization). Since HTTP is a stateless protocol, cookies are common in web development to maintain information and state. Cookies are sent with every HTTP requests, so try to keep them low in size to minimize effects on the HTTP response.
Cookie’s size should be minimized as much as possible.
Cookies shouldn’t contain secret information. If really needed, that information should be either encrypted or encoded.
Try to minimize the number of cookies by removing unnecessary cookies.
Cookies should expire as soon as they become useless for an application.

11. Use Cache appropriately

Cache mechanism is a great way to save server round trips - and also database server round trips - as both round trips are expensive processes. By caching data we can avoid hitting them when unnecessary. Following are few guidelines for implementing caching::
  • Static contents should be cached, like “Contact us” and “About us” pages, and such other pages which contain static information.
  • If a page is not fully static, it contains some dynamic information. Such pages can leverage the ASP.NET technology, which supports partial page caching.
  • If data is dynamically accessed and used in web pages - like data being accessed from some file or database - and even if data is consistently or regularly changed, then that data could be cached by using ASP.NET 2.0 cache dependency features. As soon as data changes from the back-end by some other means, the cache would be updated.
Now that web technologies such ASP.NET have matured and offer such great caching capabilities, there's really no reason not to make extensive use of them.
Following are few very good links to implement caching for different types of data (static and dynamic):
  • Click here to cache Full page (static page caching).
  • Click here and here to cache partial page caching.
  • Click here to cache dynamic data with dependency.

12. Upload compiled code rather than source code

Pre-compiled ASP.NET pages perform much better than source code versions. Actually pre-compilation give web sites a performance boost especially when the first request is made to a folder containing that resource.
Uploading a pre-compiled version boosts up performance since the server doesn’t need to compile a page at request-time.

13. Conclusions

Following are few good practices to gain better performance::
  • For HTTP compression, GZip is considered the most effective and most popular by means of browsers and HTTP server. It can reduce file size up to 70% in size.
  • Always keep JavaScript and CSS in external files.
  • Avoid redirects until needed. Server.Transfer is also provided so consider that as well since it performs better in some conditions.
  • Minimize use of Iframes as it's costly.
  • Avoid try-catch blocks for control-flow as they perform poorly. Exceptions should be used only in truly exceptional situations.
  • Minimize Cookie/CSS sizes.
  • Minimize DOM objects on page as they are heavy weight.
  • Use link tags rather than @import to use/link up CSS.
  • Favicon, being a static image displayed in the browser’s address bar, should be cacheable and compressed.
  • Always prefer a cache-friendly folder structure. For example, create specific folders for static contents, like /static for static images/static pages…
  • SSL can never be cached so minimize its usage. Keep it for those pages which need to be secure, rather than using it for all the pages.
  • HTTP Post requests can’t be cached, so choose the HTTP method appropriately.
  • Prevent Denial of Service (Dos) attacks. Recommended article here.
  • Prevent SQL Injection. Recommended article here.
  • Prevent Cross Site Scripting (XSS). Recommended article here.
I hope you have learned some very good approaches and techniques to keep your web application in good shape on an HTTP server. I personally don’t think any are flat-out ignorable nor is any too difficult to implement.
As performance is a vital part of success for any web application, I have tried to be as general as possible, so every web technology (ASP.NET, asp, php, jsp, jsf and so on) can follow these tips.

Best Practise for Improving .NET Application Performance and Scalability

Best Practise for Improving .NET Application Performance and ScalabilityThis guide provides end-to-end guidance for managing performance and scalability throughout your application life cycle to reduce risk and lower total cost of ownership. It provides a framework that organizes performance into a handful of prioritized categories where your choices heavily impact performance and scalability success. The logical units of the framework help integrate performance throughout your application life cycle. Information is segmented by roles, including architects, developers, testers, and administrators, to make it more relevant and actionable. This guide provides processes and actionable steps for modeling performance, measuring, testing, and tuning your applications. Expert guidance is also provided for improving the performance of managed code, ASP.NET, Enterprise Services, Web services, remoting, ADO.NET, XML, and SQL Server.

Part I, Introduction to Engineering for Performance

This part shows you how to apply performance considerations throughout your application life cycle and introduces fundamental performance and scalability concepts and terminology. Part I includes one chapter:

Part II, Designing for Performance

Performance modeling helps you assess your design choices before committing to a solution. By considering from the start your performance objectives, workload, and metrics for your scenarios, you reduce risk. Use the design guidelines chapter to learn practices, principles, patterns, and anti-patterns that will help you to make informed choices. Part II includes three chapters:

Part III, Application Performance and Scalability

This part provides a series of chapters that provide deep platform knowledge across the .NET Framework technologies. Use these chapters to learn about the key performance and scalability considerations for the various .NET technologies, and to improve the efficiency of your code in these areas. Part III includes nine chapters:

Part IV, Database Server Performance and Scalability

This part shows how to improve SQL Server performance. This part includes one chapter:

Part V, Measuring, Testing, and Tuning

This part shows which metrics monitor and analyze for specific performance aspects. It also explains how to load, stress, and capacity test your applications and how you can tune performance with appropriate application, platform, and system configuration. This part includes three chapters:

Checklists

This section contains printable, task-based checklists, which are quick reference sheets to help you put the information and details that you learned in the individual chapters into action. This section includes the following checklists:

How To Articles

This section contains How To articles that provide step-by-step procedures for key tasks. This section includes the following How To articles:

Tuesday, 16 October 2012

WPF and Silverlight Code Performance

As WPF and Silverlight sit on the .NET framework, they’re subject to the rules of the Garbage Collector. That means there are a few unique ways in which WPF will cause your application to leak memory, and Chris Farrell points out the most prominent culprits.

As I’m sure you know, WPF and Silverlight both use XAML as their interface markup language. The idea is that you can define your user interface (UI) and bind it to data without ever writing a line of code (healthy skepticism advised). Whether or not you buy into that vision, the UI possibilities can be stunning, and it seems Microsoft has created a technology that combines both power and flexibility. However, with that power comes responsibility.

It’s with an eye on that responsibility that I write this article, in which I want to talk about some of the problems that you can introduce into your application without even realizing it.

Background

.NET uses a garbage collector to reclaim and reuse the space left behind when objects are no longer needed. To do this, it builds a list of all objects that are still ultimately referenced from an application root, such as the stack, other objects on the heap, the CPU and statics, to name just a few. Everything else (i.e. objects which have no such references) is assumed to be garbage, and the .NET framework rearranges memory allocation to reuse the gaps these objects filled.

A leak (or, if you’re being picky, leak-like behavior) occurs when a section of code fails to release references to objects it has finished working with. The smaller the leak, the greater the number of iterations that must occur before it becomes a noticeable problem. The larger the leak, the more obvious the problem.

A really obvious example of this problem is adding an object to a static collection and then forgetting about it. Other common ones involve event handling, which we will discuss later. The simple fact is that if you leave a reference to an object behind, and that reference traces back to an application root, then you have a leak.

 

heavyweight User Interfaces in xaml

Silverlight and WPF applications are state-full, and allow us to hold state in the form of complex data structures as well as rich UI elements such as images and media. All of this “stuff” adds to the size of the views we create and, ultimately, the size of a memory leak when things go wrong. If you have a memory leak that involves a complex UI then it can quickly become a major problem, especially if users are constantly opening and closing windows as part of standard flows.

Just as an example of how the way these problems can scale, this is exactly the situation I found with a large financial application written in WPF, employing all the usual accounting/finance type windows, often containing many hundreds of rows of data. As you would expect, the developers had taken full advantage of data binding and the entity framework. It looked great and all seemed well until, during system testing, they discovered that the application would get slower over time and ultimately crash the machine. Eventually they actually had to reboot to get over it. Naturally I suspected a memory leak, but nothing could prepare me for the extent of the issues I actually found (but that’s a different story).

Some of the issues we’ll cover are specific to WPF/XAML and Silverlight, and others are general leaks you will get in any application. I thought it would be useful to go through the main technology-specific leaks you can easily create; thankfully, the good news is that they are easy to fix and avoid in the future.

WPF and Silverlight leaks

While I‘ve tried to come up with a list of the most likely leaks, the trouble is that, depending on platform and framework versions, there are many potential leak mistakes you can make. Regardless, you’ve got to start somewhere, and these points will always serve you well. You’re likely to quickly see a pattern emerging in the underlying nature of the problems and solutions I highlight, but I do recommend you read to the end, because I almost guarantee that you’ll encounter one or more of these situations sooner or later.

Unregistered events (WPF + Silverlight, All versions)

Let’s start with the classic leak, common to all .NET applications - the event leak. While this is a common source of leaks for all .NET applications, it’s not a bug in .NET, but rather a common oversight by developers.
Specifically, if you create an event handler to handle events occurring in some object, then if you don’t clear the link when you have finished, an unwanted strong reference will be left behind.

The Issue

My contrived example below deliberately isn’t specific to WPF/Silverlight, but I include it because it’s a very common memory leak which all .NET applications are vulnerable to. In it I am subscribing to an OnPlaced event on my Order class. Imagine this code executes on a button click. Basically, it sets up an order for a currency exchange to take place when certain price conditions are met:

Order newOrder=new Order(“EURUSD”, DealType.Buy, Price PriceTolerance, TakeProfit, StopLoss);
newOrder.OnPlaced+=OrderPlaced;
m_PendingDeals.Add(newOrder);

Listing 1

When the price is right, an Order completes and calls the OnPlaced event, which is handled by the OrderPlaced method;

void OrderPlace(Order placedOrder)
{
      m_PendingDeals.Remove(placedOrder);
}
Listing 2 

In the event handler, you can see that we are already eliminating a really common source of leaks; namely, references from collections (in this case the m_PendingDeals collection).

However, the OrderPlaced event handler still holds a reference to the Order object from when we subscribed to the OnPlaced event. That reference will keep the Order object alive even though we have removed it from the collection. It’s so easy to make this mistake.

The Solution

The OrderPlaced method is just one line away from avoiding a memory leak!

void OrderPlaced(Order placedOrder)
{
      m_PendingDeals.Remove(placedOrder);
      placedOrder.OnPlaced-=this.OrderPlaced;
}

Listing 3

The last line unsubscribes the event and removes the strong reference. If this is news to you, then drop everything and look at all your event handling code. Chances are you have a leak.

Databinding (WPF + Silverlight, All versions)

You read that right; data binding, the thing you rely on, can cause memory leaks. Strictly speaking it’s actually the way you use it that causes the leak and, once you know about it, it’s easy to either avoid or code around this issue.

The Issue

If you have a child object that data binds to a property of its parent, a memory leak can occur. An example of this is shown in Listing 4, below.

<Grid Name="mainGrid">
           <TextBlock Name=”txtMainText” Text="{Binding ElementName=mainGrid, Path=Children.Count}" />
</Grid>

Listing 4: DataBinding Leak Example

In this example, the condition will only occur if the bound property is a PropertyDescriptor property, as Children.Count is. This is because, in order to detect when a PropertyDescriptor property changes, the framework has to subscribe to the ValueChanged event, which in turn sets up a strong reference chain.

If the binding is marked as OneTime, the bound property is a DependencyProperty, or the object implements INotifyPropertyChanged, then the issue won’t occur. In the case of OneTime binding this is because, as the name suggests, it doesn’t need to detect property changes, as the binding occurs from data source to consumer just once.

Solution

There are a number of work-arounds for this problem.
  1. Add a DependencyProperty [to the page/window] which simply returns the value of the required PropertyDescriptor property. Binding to this property instead will solve the problem..
  2. Make the binding OneTime

    Text="{Binding Path=Salary, Mode=OneTime}"/

    Listing 5
  3. Add the following line of code on exit from the page:
    BindingOperations.ClearBinding(txtMainText, TextBlock.TextProperty);

    Listing 6
    (This simply clears the binding and removes the reference.)

Static events (WPF + Silverlight, All versions)

Subscribing to an event on a static object will set up a strong reference to any objects handling that event. Statics are a classic source of root references, and are responsible for a high proportion of leaks in code.
Statics, once referenced, remain for the duration of the app domain execution, and therefore so do all their references. Strong references preventing garbage collection are just memory leaks by another name.
To show you what I mean, the code below subscribes the calling class to the event source, EventToLeak, on the static object MyStaticClass:

MyStaticClass.EventToLeak += new EventHandler(AnEvent);

Listing 7

The handling event, AnEvent, will be called when the EventToLeak event fires:

protected override void AnEvent(EventArgs e)
{

  // Do Soemething

}
Listing 8

If you don’t subsequently unsubscribe the event, then it will leak because MyStaticClass continues to hold a strong reference to the calling class.

The Solution

To unsubscribe, simply add the code line:

MyStaticClass.EventToLeak -= this.AnEvent;
This releases the strong reference from MyStaticClass. It’s a simple solution, but then it’s a simple problem – human error and oversight.

Command Binding

Command binding is a really useful feature in WPF; it allows you to separate common application commands and their invocation (such as Cut, Paste, etc ) from where they are handled. You can write your classes to handle specific commands, or not, and even indicate if those commands can be executed. As useful as these bindings are, you do have to be careful about how you use them.

The Issue

In the following example I am setting up some code within a child window to handle when Cut is executed within the parent mainWindow. I first create a CommandBinding, and then simply add it to the parent window’s CommandBindings collection.

CommandBinding cutCmdBinding = new CommandBinding(ApplicationCommands.Cut, OnMyCutHandler, OnCanICut);            
 mainWindow.main.CommandBindings.Add(cutCmdBinding);


…..
void OnMyCutHandler (object target, ExecutedRoutedEventArgs e)
{
   
    MessageBox.Show("You attempted to CUT");
}


void OnCanICut (object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}

Listing 9

You may be able to see what the problem is just from reading the code above because, at the moment, it leaks. It’s because we are leaving a strong reference in the mainWindow.main.CommandBindings object, pointing to the child. As a result, even when the child closes, it will still remain in memory due to the held reference.

This is obviously a contrived example to illustrate the point, but you can easily set this scenario up without even realizing it.

The Solution

Again, the solution couldn’t be easier and, not surprisingly, involves removing the command binding reference:

mainWindow.main.CommandBindings.Remove(cutCmdBinding);
Listing 10
Once this reference is removed, the leak will go away.

DispatcherTimer Leak

Improper use of the DispatcherTimer will cause a memory leak. There’s not much more background to this, so let’s just jump right in.

The problem

The code below creates a new DispatcherTimer within a user control. A textbox is updated with the contents of the count variable, which is updated every second by the DispatcherTimer. To make it easier to see the leak, I have also added a byte array called myMemory, which just makes the leak much bigger and easier to see.

        public byte[] myMemory = new byte[50 * 1024 * 1024];
       
        System.Windows.Threading.DispatcherTimer _timer = new System.Windows.Threading.DispatcherTimer();
        int count = 0;
       

        private void MyLabel_Loaded(object sender, RoutedEventArgs e)
        {

            _timer.Interval = TimeSpan.FromMilliseconds(1000);

            _timer.Tick += new EventHandler(delegate(object s, EventArgs ev)

            {
                count++;
                textBox1.Text = count.ToString();
            });

            _timer.Start();
        }

Listing 11

On my main window, I am adding an instance of the UserControl to a StackPanel (after removing children first) on a button click. This will leak memory for every button click and, as mentioned a moment ago, in this example the main leak you will see is the byte array. Tracing it backwards (using ANTS Memory Profiler in this case, though any profiling tool will do) shows that the UserControl as the source of the leak.

This probably feels familiar, as the problem is once again a reference being held, this time by the Dispatcher, which holds a collection of live DispatcherTimers. The strong reference from the collection keeps each UserControl alive, and therefore leaks memory.

The Solution

The solution is really simple but easy to forget and, you guessed it, you’ve got to stop the timer and set it to null. Here’s the code to do that:
_timer.Stop();
_timer=null;
Listing 12

TextBox Undo Leak

The last leak I want to draw your attention to is not really a leak; it is intended behavior, but it’s important to know it’s there.

The Problem

The problem is to do with the TextBox control and UNDO. TextBoxes have built-in undo functionality, enabling a user to undo their changes to the contents of a text box. To achieve that, WPF maintains a stack of recent changes, and when you use a memory profiler, you can clearly see a build up of data on this undo stack.
This isn’t a major problem unless your app is updating large strings to text boxes over many iterations. The main reason to note this behavior is because it can often show up on memory profile traces, and there is often no point being distracted by it.

The solution

You can limit the behavior of the undo stack by either switching it off:
textBox1.IsUndoEnabled=false;
Listing 13

Or alternatively you can reduce its impact by setting the UndoLimit property:

textBox1.UndoLimit=100;

Listing 14

This limits the number of actions that can be undone, in this case to 100. By default the setting is -1, which limits the number of actions only by the amount of memory available. Setting the value to zero also switches undo off.

Conclusion

None of this is rocket science, and it’s all based on the same principle: “leave a reference behind and potentially you have a leak”. Obviously that depends on whether the left reference is ultimately connected to a root reference.

While nothing I have covered is strictly speaking a bug, all of the points are definitely gotchas that you can easily be caught by without realizing it.
I should know, because I see them all again and again in the projects that I work on.

Ultimately, the two things I recommend you do to avoid memory leaks in the future are:
  • Learn all you can about .NET memory management and how your code impacts it
  • Get used to routinely using a memory profiler and interpreting it’s results to trace issues such as the many potential flavors of left behind strong references.