Automatic Inspections
dotMemory can automatically analyze snapshots and detect a number of memory issues.
String duplicates
Repeatedly creating strings with the same value instead of reusing the existing one wastes memory. dotMemory detects duplicated strings and shows how much memory is wasted.
To analyze the objects
Click the link in the inspection header or double-click a particular object set in the list.
To fix the issue
If strings with the same value waste a huge amount of memory or generate significant traffic (for example, if your app parses text input) consider implementing string interning.
Sparse arrays
Sparse arrays are arrays that are mostly filled with zero elements. Sparse arrays are inefficient from the perspective of performance and memory usage. dotMemory automatically finds sparse arrays and shows you how much memory is lost (occupied by zero values) because of them.
To analyze sparse arrays
Click the link in the inspection header or double-click a particular object in the list.
Finalizable objects
Finalizable objects are the objects that use the Finalize()
method to release unmanaged resources. The problem of using this pattern is, first, that the lifetime of finalizable objects is extended by at least one more GC cycle and, second, that the finalization thread (that executes the Finalize()
method) is run unpredictably. This may cause problems in case you want to reclaim the released resources as quickly as possible and may lead to sudden performance drops. dotMemory detects and shows all objects queued for finalization and objects finalized since the previous snapshot.
To analyze finalizable objects
To fix the issue
Implement the
IDisposable
interface for the type that causes issues and release all unmanaged resources via itsDispose()
method. For more information about the dispose pattern, refer to Microsoft Learn.
Event handlers leak
Such a leak occurs when you subscribe an object (let's call it listener) to an event of some other object (let's call it source). For example: Timer1.Tick += OnTimer;
During subscription, the source object gets a reference to the event handler of the listener object. If you delete the listener, this reference will prevent it from being garbage collected. dotMemory automatically finds objects that are referenced in event handlers but are never unsubscribed from corresponding events.
To analyze the objects
Click the link in the inspection header or double-click a particular object in the list.
To fix the issue
Unsubscribe the listener from the event when it is no longer needed. For example:
Timer1.Tick -= OnTimer;
WPF binding leak
Breaking WPF data binding patterns also can cause a memory leak. After you perform data binding to some property of a source object, the binding target object starts to listen for property change notifications. If the property is not a DependencyProperty
object and the target object doesn't implement the INotifyPropertyChanged
interface, a memory leak in the source object and in every object to which the source object refers may occur. dotMemory detects such binding pattern violations and shows you the list of objects that may potentially cause this leak type.
To analyze the objects
Click the link in the inspection header or double-click a particular object in the list.
To fix the issue
Make the source object implement the
INotifyPropertyChanged
interface or remove binding when it is no longer needed using theClearBinding
method.
WPF collection binding leak
This leak is similar to the WPF binding leak described above. If there is binding to a collection, that doesn't implement the INotifyCollectionChanged
interface, WPF creates a strong reference to this collection. As a result, it stays in memory for the entire application lifetime. dotMemory detects and shows you such objects.
To analyze the objects
Click the link in the inspection header or double-click a particular object in the list.
To fix the issue
Make the source collection implement the
INotifyCollectionChanged
interface. Another way is to use theObservableCollection
collection as it already implements theINotifyCollectionChanged
interface.
Dependency property leak
Such leaks occur due to the same reasons as the event handlers leak. Garbage Collector will not collect objects subscribed on DependencyProperty
changes through the AddValueChanged
method until they're unsubscribed using the RemoveValueChanged
method. dotMemory detects and shows you all such objects.
To analyze the objects
Click the link in the inspection header or double-click a particular object in the list.
To fix the issue
When the lifetime of a subscribed object is over, take care of unsubscribing it using the
RemoveValueChanged
method.
x:Name WPF leak
Such leaks take place because of the following WPF peculiarity: WPF creates a strong global reference to the UI element that is declared in XAML and uses the x:Name directive. For example:
Thus, if you dynamically remove the element declared in such a way, it will still be in memory.
To analyze the objects
Click the link in the inspection header or double-click a particular object in the list.
To fix the issue
One way to remove the leak is to declare the UI element in the C# code instead of XAML. Another way is to call the
UnregisterName
method of the parent control when you want to remove the UI element. For example:this.UnregisterName("myControl1");