The concept of memory leakage in .NET applications is slightly different from native application memory leaks, but the problem of leaking code still exists in managed world. .NET applications can leak memory and run out of resources when unused objects are still referenced by other objects and cannot be cleaned by Garbage Collector.
Visual Studio 2013 provides Performance and Diagnostics tools to analyze such memory issues, and with release of Update 3, these tools cover WPF application analysis.
Many of the memory leaks in WPF applications are related to event handlers and the following code demonstrates usage of Diagnostics tools for analyzing such issues (source code is also available on GitHub).
The Test application is composed from two windows:
On the Button_Click event, MainWindow opens SecondWindow.
SecondWindow allocates some memory and subscribes itself to Application’s Deactivated event. This is an obvious memory leak – SecondWindow will stay in memory even after close.
Analyzing memory issue with Performance and Diagnostics tools
In less obvious cases, when code review is not enough for identifying potential memory leaks, the application can be inspected using the Memory Usage tool.
This tool allows taking several memory snapshots and comparing them to identify differences. The Profiler can collect information on native and managed memory operations – it is controlled by tool’s setting.
The following picture demonstrates two memory snapshots for the test WPF application. The first snapshot represents the application’s state immediately after start. The second snapshot demonstrates memory usage after several openings of SecondWindow.
Each snapshot automatically triggers the Garbage Collector (indicated by red triangles on the timeline), so the memory represented by snapshot is compacted and all unused objects are disposed.
When a potential issue is captured in the series of snapshots, the session can be stopped.
The first row of numbers in each snapshot represents the actual heap size. The second row compares the current heap size with the previous snapshot’s heap. All these numbers are links that lead to the detailed heap information. Reviewing the differences in the selected snapshots helps to identify trends and isolate unexpected objects in memory.
The following snapshot details clearly identifies SecondWindow as an issue and EventHandler as a root cause.
Additionally, the details view supports several filters and review modes that may be helpful for analyzing other types of memory issues.
The .NET community has developed a few tools and techniques for dealing with memory issues in managed code. Visual Studio 2013 adds a simple, easy to use tool in developer’s toolbox and enables continuous memory analysis without distracting the typical Visual Studio workflows.