Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UWP compiled binding x:Bind produces memory leaks

While developing UWP application I recently found quite a few memory leaks preventing my pages from being collected by GC. I have a ContentPresenter on my page like:

<ContentControl Grid.Column="0" Grid.Row="1" Content="{x:Bind ViewModel.Schedule, Mode=OneWay}">
</ContentControl>

After I remove the Content, or replace it with dynamic {Binding} -- page is collected when I navigate from it. Otherwise it remains in memory. Is it bug or I'm doing something wrong? Is there a way to release and clear ALL the bindings on navigating from?

UPDATE: It seems to be a known problem inside Microsoft as was stated here. But as far as I can see through my own test/app usage the data that is preserved by the x:Bind still gets collected after some time, when you, for example, navigate to the same pages or create the same controls for some time. I could see that new objects were created, but old ones at some point got collected.

So for me it doesn't seem to be a drastic problem causing out of memory, it only doesn't allow objects get collected as quickly as dynamic binding will.

like image 325
Viachslau Avatar asked Sep 15 '15 08:09

Viachslau


2 Answers

I have created bug on Microsoft connect because of this issue.

https://connect.microsoft.com/VisualStudio/feedback/details/3077894/memory-leaks-in-c-uwp-apps-using-compiled-x-bind-bindings

Work around for this issue is to explicitly call Bindings.StopTracking() at page Unloaded event handler. It's because compiled bindings doesn't use "weak event" pattern and does subscribe to PropertyChanged event of INotifyPropertyChanged directly. It's a cause of memory leak. To unsubscribe events you can call Bindings.StopTracking(). Compiled bindings code doesn't call it automatically.

like image 171
Evgeny Ipatov Avatar answered Nov 14 '22 14:11

Evgeny Ipatov


Yes it does cause memory leak, to prevent that you can use following steps:

  1. Use IoC like UnityContainer and make your ViewModel or View ContainerControlLifeTime
  2. Assign null to ViewModel property at xaml.cs once you move out of UI.
like image 37
Prashant Soni Avatar answered Nov 14 '22 15:11

Prashant Soni