Latest version: 4.3
Notes & articles
Finding memory leaks using ANTS Profiler
One of the more common tasks that ANTS Profiler is used for is to find memory leaks. In addition to gathering statistics about an application's performance, ANTS Profiler can also track objects created in the .NET managed runtime, making it a solid tool for finding objects that are not being freed when they are no longer being used.
A memory leak, technically, is an ever-increasing usage of memory by an application. With common desktop applications, this may go unnoticed, because a process typically frees any memory it has used on application exit. In the client/server model, however, memory leakage is a serious issue, because applications are expected to be available 24 hoursThis a day with little or no downtime. Applications must not continue to increase their memory usage indefinitely, because that can result in a service being unavailable, or even create a stoppage for the entire computer on which the service is running!
To illustrate this, you can normally tell that an application is leaking memory if you use the Windows Performance Monitor tool, and look at its # Total committed Bytes performance counter for the .NET CLR Memory performance object. During normal usage of the application, you would see the memory usage continue to creep upwards.
Microsoft's .NET runtime uses a technique known as "garbage collection" to manage memory. The garbage collector kicks in from time to time, and cleans up the memory of objects that are no longer within the "scope" of the application. (Jeffrey Richter has written two detailed articles on garbage collection in the CLR. See http://msdn.microsoft.com/msdnmag/issues/1100/gci/ and http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/
In theory, programmers should never need to worry about memory leaks. But in practice, there are technical reasons why some objects survive garbage collection even though it appears that they're no longer being used.
Now that we realize that there is a problem, we need to find the reason for it. You can use ANTS Profiler's memory profiling project to identify the number of objects that survive .NET's garbage collection, and then amend your code so that the objects are freed from memory when no longer needed.
The first step in identifying a typical memory leak is to start profiling your application by setting up a new project in ANTS Profiler, choosing the type of project, setting the appropriate arguments, and clicking GO. ANTS Profiler can analyze the object allocations for desktop applications, .NET web applications and services, Serviced Components hosted in COM+, and Windows Services. In order to profile ASP .NET web applications, membership in the local administrators' group is necessary. The first example here is a simple ASP .NET web application with the following code-behind file:
Note that this code isn't functional; it merely illustrates the creation of a few objects. The auto-generated code is omitted for brevity, but the code is otherwise correct, and runs without any errors.
After clicking GO, the web application displays in a browser window. The page is refreshed 20 times, so that the number of "live objects," that is, objects that survive garbage collection, can be counted. After this, go back to the ANTS Profiler window, and click Take Snapshot.
This generates the results. Because a lot of objects are allocated by ASP .NET, the MemLeakWebApp doesn't appear in the summary's Biggest Live Objects or Classes with the most live instances sections. Clicking the All Classes tab allows viewing of classes within the MemLeakWebApp namespace, which is the namespace for the code behind being analyzed. This is the All Classes information:
The only class created in the MemLeakWebApp namespace is the MyHandler1 class, of which 21 instances had survived garbage collection. Is this the desired result? Probably not. The MyHandler1 class needs to be attached to the MyStaticClass.EventHandler property. This should only be used once per page load. The question is, why are these classes surviving many page loads?
The answer to this particular question is that the MyStaticClass instance is, in case it's not entirely obvious, static. This means it will survive as long as the web application process continues to run. The net effect is that the MyStaticClass is having a new EventHandler attached at every page load. The solution is to create MyStaticClass as a public class, rather than static. A new MyStaticClass will be created at every page load, and disposed of when the page has finished loading.
In order to test the code changes, run ANTS Profiler once more by clicking GO, and refresh the web page 20 more times. This should demonstrate that a complex problem has been easily solved, hours before lunchtime!
The results now show a live count of zero, indicating that the application is not leaking memory, but still functions properly.
In addition to identifying memory leaks caused by objects that could not be freed because they are still referenced, ANTS Profiler's memory profiler can also show the single objects that use the most memory. The solutions to this are usually more obvious. For instance, if a web application is performing poorly, it's possible to analyze the session size. If there is a lot of data in each session, the data could be reduced by limiting the columns or rows queried from a SQL Server table, for example. In this case, there is an object in the user session that takes up 118 kilobytes of memory. Technically, this is not going to cause a memory leak, but if thousands of users access this website, the memory usage would continue climbing, causing problems on the web server.
Part of the art of finding memory leaks is that some answers come by thoroughly investigating the results. The application that produced the performance monitor results in the very first screenshot had a problem that could not easily be identified using the Biggest live objects or the Classes with the most live instances. This is the application's code:
This is the result of memory profiling the application. There was no high live count for any objects, but there are 1,000 separate classes in the Microsoft.Xslt.CompiledScripts.CSharp namespace. This application has caused the .NET Framework to dynamically generate 1,000 compiled assemblies, the same number as the number of iterations of the program's loop.
Some research on the Internet leads here:
This article describes a memory leak issue that happens because loading an XSL template file causes a dynamically-compiled assembly to be generated and referenced. There are two solutions: the first is to move the xslt.Load method outside the loop, so it will only run once. If this can't be avoided, the second solution is to call AppDomain.Unload, which will free the memory.
Choosing to run the xslt.Load() method only once fixes the memory leak:
Running the performance monitor against the application again, just to make sure, results in an indication that the memory usage has stabilized.
In this paper, various causes of memory leaks have been explored, providing reproducible examples of some common scenarios where memory cannot be reclaimed by the garbage collector in the .NET runtime. Various methods for analyzing different causes of memory leaks have been discussed: over-use of memory by objects that are larger than necessary, objects that cannot be freed because they are still referenced by the application, and memory leaks that occur because of technical issues deep within the inner workings of the framework.
ANTS Profiler has been demonstrated to be a vital tool in identifying and remedying these memory issues.
Was this article helpful?
Thanks for your feedback!
- Enabling logs to track the profiling session
- Changing the interprocess communications ports in version 4
- Double hit counts occurring on one line
- System.EntryPointNotFoundException (Versions: 3,4 only)
- Version 3.0 Unhandled startup exception on Windows Vista
- Version 3 add-in grayed out on non-English Visual Studio 2005 and 2008
- Methods in (ASCX) web controls may not appear
- Failed to CoCreate Profiler error profiling a Windows service
- Multiple-core portable computers may show inflated times (version 3)
- No .NET methods were profiled on web application
- ANTS Profiler code instrumentation method
- Profiling a single assembly in version 3
- Filtering results by individual thread
- Add-in fails to load when using RunAs to start Visual Studio as another user
- Profiling unit tests using Nunit
- Can I profile Compact Framework applications?
- Profiling a SharePoint 2007 Web Part
- Profiling an assembly in the Global Assembly Cache (GAC)
- Additional hidden statistics in the results grid (version 3)
- Multiple floating ANT icons in Visual Studio (version 3)
- ANTS Profiler overhead adjustments
- Profiling IIS web applications that need to run under the SYSTEM account
- Profiling a web application hosted in IIS on a fixed TCP port
- Add-in 'Object Reference not set to an instance of an object' error
- Profiling client-side XBAP .NET applications
- ANTS Profiler prompts for location of source code which is not your own source code
- ANTS menu remains in Visual Studio after uninstall of ANTS Profiler
- Profiling a web application needing to run as the Network Service account
- Abnormal termination caused by .NET 2.0 critical finalizer threads
- Cannot start COM+ application via Remote Desktop
- Fast mode and memory profiling options unavailable
- Finding the overall time taken to execute a thread
- Running an IIS application pool as a named identity
- IIS web application always loads default website
- Profiling BizTalk applications
- Profiling Microsoft Office managed-code add-ins
- The system cannot find the file specified
- Error Stopping IISAdmin profiling IIS web application on Windows XP
- ANTS Memory Profiler total size of all objects does not match the memory footprint of an application
- Lines of source code do not align with hit count, time data in version 3
- Creating a global debugging symbols (PDB) directory
- Profiling a SharePoint site collection
- Using the add-in to profile solutions containing more than one project
- Methods may be missing on multi-core systems in version 3
- ASP .NET 1.x application recycling causing incomplete results
- Ambiguous site selection message when profiling IIS applications
- Application recycling causes incomplete results and other errors when profiling ASP .NET
- Profiling WCF services hosted in IIS
- Cannot profile IIS 6 web application on port lower than 1024
- (version 5) Support for profiling Silverlight applications
- Couldn't open metabase error when profiling ASP .NET hosted in IIS
- Failed to coCreate Profiler on ASP .NET web application
- HTTP error 404.17 profiling ASP .NET 1.1 on IIS 7
- Performance counters missing from results
- Isolating single ASP .NET pages in ANTS Profiler results
- Missing hits for lines in the source code view
- ANTS Profiler restarts IIS
- Showing the amount of time taken for a method in one particular thread
- Common ASP .NET memory issues
- Please specify a valid URL message profiling ASP .NET
- Times on individual lines do not add up to method time
- Manually installing the add-in
- Error starting services running as "Local Service"
- Explanation of "thread blocked" methods in ANTS Profiler
- Call graph percentages do not add up exactly
- Operation could destabilize the runtime error profiling ASP .NET
- IIS ceases to work after profiling web applications
- Access to the Temp directory is denied error profiling web applications
- Problems with ANTS Visual Studio integration
- Unable to coCreate Profiler error profiling any application
- Some Red Gate products identified as containing a trojan by Anti-Virus software
- Activation may fail with Unknown Error -1
- Product uses web help although a CHM file is available locally
- Argument exception resulting from missing environment variable
- Check for updates may fail when used through proxies
- 'Unidentified Publisher' error when repairing or uninstalling
- Licensing activates product as standard edition
- Moving Red Gate software products to another machine
- Red Gate tools log locations
- The application UI opening slowly when there is no internet access
- Getting help offline
- Finding memory leaks using ANTS Profiler
- Identifying root objects with ANTS Profiler
- Performance profiling with ANTS 4: tips for ANTS 3 users
- How to profile a desktop application that hosts the .NET runtime (ANTS Profiler 3)
- How to profile the performance of a single .NET assembly (ANTS Profiler 3)
- Profiling ASP.NET applications (ANTS Profiler 3)
- How to reduce the number of topics you see in the "All objects" panel (ANTS Profiler 3)
- ANTS Profiler release notes - version 4.xx
- Why can't ANTS Profiler find my source code? (ANTS Profiler 3)
- Red Gate product acknowledgements
- Activating your products
- Activating your products
- Red Gate bundle history
- Check for updates
- Troubleshooting Check for Updates errors
- Current versions
- Deactivating your products
- Installing Red Gate products from the .msi file
- Requesting additional activations
- Serial numbers for bundles
- Reactivating using a different serial number
- Extending your trial
- Finding your serial numbers
- Moving a serial number from one computer to another
- No response received for manual activation
- Licensing and activation resources
- Licensing and activation resources
- Troubleshooting licensing and activation errors
- Licensing and activation FAQs
- Red Gate tools log file locations
- Download old versions of products
- Download product prerequisites & utilities
- Support & upgrades
- Upgrading your software
- Upgrading FAQs