In our SL4 application built on Caliburn.Micro, we've come across a (another) memory leak.
Stripped out, it seems that the problem is caused by ItemsControl with custom DataTemplate bound to an IEnumerable collection of objects that implement INotifyPropertyChanged interface.
When the source collection is changed (another collection is assigned to the ViewModel's property that the ItemsControl's ItemsSource is bound to), the entites in the original collection and bound DataTemplates are not garbage collected. Although the event handling of NotifyPropertyChanged seems to be done internally via WeakReference, it is like SL is keeping another reference to these objects. So every time we refresh data from the server, memory consumption increases.
Do you have any idea how to solve this problem? I really cannot understand how can this kind of bug happen in SL4!
Some experiments suggested that calling ItemsControl.Items.Clear() could help. Any tip how to simply call this every time the ItemsSource is changed? The only thing that comes to my mind would be to override ItemsSourceProperty and add a handler there.
EDIT: It turned out that the leak occurs in this situation:
- load entities through RIA services context and store a collection of them in a property of viewmodel
- bind a listview with custom data template to the property with collection of entites
- refresh the entites via RIA services context
What happens is that although the entities get refreshed, which can be seen in the view, memory consumption is rising.
If there is no binding, refreshing the entities does not eat more memory (it might but the memory consumption level eventually returns back as GC does its job).
If you clear the context or simply create a new one, the memory is also eventually collected.
It seems that the problem is connected with RIA services.
I can provide a simple project that shows the problem if you want.
UPDATE: The memory leak seems to be caused by INotifyDataErrorInfo. Read here.