ANTS Memory Profiler - 7.4
.NET memory management primer - ANTS Memory Profiler
This topic is intended as an overview of .NET memory management. It should give you enough information about how .NET allocates objects into memory to start using ANTS Memory Profiler.
Large and small objects
.NET handles large objects and small objects differently:
- Large objects are all objects over 85k, and double (multidimensional) arrays over 8k.
- All other objects are considered small objects.
The small object heaps
Small objects are stored in the small object heaps.
Objects are allocated first to the generation 0 (Gen 0) heap.
When the Gen 0 heap is full, the .NET garbage collector runs. The garbage collector performs two tasks:
- It disposes of all objects on the Gen 0 heap that are no longer needed.
- It moves objects that are still needed to the generation 1 (Gen 1) heap.
This leaves the Gen 0 heap empty, ready for new objects to be allocated on it.
Eventually, the Gen 1 heap becomes full. When this happens, the garbage collector runs again, and it performs three tasks:
- It disposes of all objects on the Gen 1 heap that are no longer needed.
- It moves objects that are still needed to the generation 2 (Gen 2) heap.
- It performs a garbage collection on Gen 0, as before.
If Gen 2 becomes full, a full garbage collection takes place. When this happens, the garbage collector performs four tasks:
- It disposes of all objects on the Gen 2 heap that are no longer needed.
- It performs a garbage collection on Gen 1, as before.
- It performs a garbage collection on Gen 0, as before.
- It disposes of objects on the large object heap that are no longer needed (see below).
If insufficient memory has been freed at the end of a full garbage collection, an OutOfMemory exception is thrown.
Note that whenever the garbage collector runs on any of the small object heaps, the heaps are compacted, so that the available space is used efficiently.
By using this generational approach, recently-allocated objects should be disposed sooner than older objects, which are presumed to be being kept in memory for a reason. It also ensures that full garbage collections, which have the greatest impact on an application's performance, happen as infrequently as possible.
Note: ANTS Memory Profiler forces a garbage collection when you take a snapshot. This is because some of the memory counters that ANTS Memory Profiler obtains from Windows are only accurate immediately after a garbage collection. For this reason, you will generally not see any objects on the Gen 0 heap during profiling. This behavior will not affect the results that you obtain, because an object which only exists for a short time on Gen 0, and which is never promoted to Gen 1, will never be the cause of a .NET memory problem.
(If you do see objects on the Gen 0 heap, it is because the .NET garbage collector does not always behave in the way described in this simplified overview. For example, pinned objects, objects on the finalizer queue and objects created during the garbage collection might remain on the Gen 0 heap after a snapshot. Again, this is never a problem that would affect the results obtained.)
The large object heap
The large object heap is where large objects are stored.
There is only one large object heap, and objects stored on it are only tidied-up during a full garbage collection.
Importantly, because compacting the large object heap would adversely affect your application's performance, the large object heap is never compacted. This means that the heap can fragment over time. If a new object, which is bigger than an existing fragment, needs to be allocated on the heap, the large object heap will grow so that the new object can be allocated to the end of the heap. Eventually, the fragmentation may mean that there is insufficient memory to allocate new large objects.
This is often a major cause of .NET memory problems, and it can be one of the most difficult issues to solve. For more information, see how to check for large object heap fragmentation.
Further information on large object heap fragmentation
- The dangers of the large object heap
http://www.simple-talk.com/dotnet/.net-framework/the-dangers-of-the-large-object-heap/ - Large object heap uncovered (MSDN)
http://msdn.microsoft.com/en-us/magazine/cc534993.aspx - Understanding garbage collection in .NET
http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/

Managed memory leaks
The garbage collector calculates whether or not an object can be disposed from one of the heaps by creating a graph (similar to the Instance Retention Graph in ANTS Memory Profiler), which shows how the object is referenced by other objects.
The graph starts from the GC roots. A GC root can be any storage slot to which the running program has access, such as a local variable, static variables, or even a CPU register. (Strictly speaking, the object itself is not the GC root; the storage slot that holds the reference to the object is the GC root.)
The GC roots will reference objects, which in turn typically reference other objects (through a member variable). If an object is not being referenced by anything, it cannot be reached by your program, and will be removed by the garbage collector.

In the graph above, System.String is referenced by:
- The key of
System.Collections.Hashtable+bucket[2].System.Collections.Hashtable+bucket[]is referenced by thebucketsproperty ofSystem.Collections.Hashtable.System.Collections.Hashtableis a GC root because it is referenced by the static variableSharedPerformanceCounter.categoryDataTable.
- The
categoryNameproperty ofSystem.Diagnostics.SharedPerformanceCounter.System.Diagnostics.SharedPerformanceCounteris referenced by thesharedCounterproperty ofSystem.Diagnostics.PerformanceCounter.(The green background means thatSystem.Diagnostics.PerformanceCounteris disposable, but not yet disposed.)System.Diagnostics.PerformanceCounteris referenced by the_instanceproperty ofSystem.Data.ProviderBase.DbConnectionPoolCounters+Counter.System.Data.ProviderBase.DbConnectionPoolCounters+Counteris referenced by theHardConnectsPerSecondproperty of the base classDbConnectionPoolCountersinSystem.Data.SqlClient.SqlPerformanceCounters.System.Data.SqlClient.SqlPerformanceCountersis a GC root because it is referenced by the static variableSqlPerformanceCounters.SingletonInstance.
Because references hold objects in memory, you have to be careful to ensure that references to objects are removed when no longer needed. A common mistake, for example, is to leave an event handler (such as a timer) referencing an object. This will stop the garbage collector from disposing the object. The result is that an object which should have been in memory only briefly can end up leaked onto the Gen 2 heap. Importantly, in this scenario, all of the objects that the object references will also be on the Gen 2 heap. This has significant implications on how you use ANTS Memory Profiler: the objects referenced by the leaked object will often be more obvious than the leaked object itself, so you need to start by investigating those referenced objects (which are most commonly strings or byte arrays).
The typical symptom of a memory leak is that the performance degrades while the program runs but the amount of memory used recovers on restart and then degrades again.
See finding and fixing a memory leak.
Further information on finding leaks in managed code
- Identify and prevent memory leaks in managed code (MSDN)
- Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework (MSDN)
- Memory Management in .NET
Unmanaged memory leaks
Managed .NET code may interoperate with unmanaged code when some COM objects or native-code DLLs are invoked.
Leaks caused by unmanaged objects are more complex to identify, because ANTS Memory Profiler cannot provide detailed information about unmanaged usage. By understanding and interpreting the data shown by ANTS Memory Profiler, however, you might gain some ideas about where to look for these leaks.
The main indication of an unmanaged memory leak is when the number of private bytes (the amount of real and paged memory requested by the program) increases while the number of bytes in the .NET heap does not grow as quickly. You may be able to find the source of the problem by looking for .NET objects whose instance count is increasing, or by looking for objects on the finalizer queue that have not been disposed.
See checking for unmanaged memory usage.
Further information on finding leaks in unmanaged code
Webinar
This page should have given you enough knowledge to start using ANTS Memory Profiler. If you are interested in learning more detail than this brief overview can provide, see our webinar 5 Misconceptions about .NET Memory Management.
Getting started
If you are new to memory profiling, we recommend that you follow this strategy to check for memory problems.
Was this article helpful?
ANTS Memory Profiler
- Installation error 5100 when installing ANTS Performance Profiler and ANTS Memory Profiler
- Attach to process unavailable with some anti-virus software
- Fragmentation notices in ANTS Memory Profiler 7
- The snapshot failed because .NET did not report every referenced object... manually switch your application to the workstation garbage collector.
- Profiling Sharepoint 2010
- Upgrading to ANTS Memory Profiler 7
- Memory leaks observed when profiling Windows Presentation Framework (WPF) applications
- Windows service profiling fails if the service uses a system account
- Log files
- The type initializer for 'y.layout.hierarchic.ClassicLayerSequencer' threw an exception
- Forcing your application to use .NET 4
- System.EntryPointNotFoundException (Versions: 3,4 only)
- Failed to CoCreate Profiler error profiling a Windows service
- ANTS Profiler code instrumentation method
- 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 IIS web applications that need to run under the SYSTEM account
- Profiling a web application hosted in IIS on a fixed TCP port
- 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
- Cannot start COM+ application via Remote Desktop
- 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
- Creating a global debugging symbols (PDB) directory
- Using the add-in to profile solutions containing more than one project
- Application recycling causes incomplete results and other errors when profiling ASP .NET
- (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
- ANTS Profiler restarts IIS
- Please specify a valid URL message profiling ASP .NET
- Operation could destabilize the runtime error profiling ASP .NET
- IIS ceases to work after profiling web applications
- ANTS Profiler has been split into two distinct programs
- Problems with ANTS Memory Profiler 5 and multiple AppDomains
- System.ArgumentOutOfRangeException or CouldNotMapFileException errors in Memory Profiler 5
- Windows Installer errors 1603 and 2738 occurring during installation
- Unable to coCreate Profiler error profiling any application
- General information about "Private Bytes"
- Profiler stopping while profiling an in-browser Silverlight application
- Error: 'Could not load file or assembly vjslib'
- "No Disk" error occurring while profiling application
- Silverlight out-of-browser profiling stops with no results
- Memory Profiler failing to profile web applications with "unable to connect to server"
all products
- 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
ANTS Memory Profiler
- Activating your products
- Activating your products
- ANTS Memory Profiler release notes - version 6.xx
- ANTS Memory Profiler release notes - version 7.xx
all products
- 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

Understanding memory problems