UWP编译绑定x:绑定产生内存泄漏

本文关键字:绑定 内存 泄漏 编译 UWP | 更新日期: 2023-09-27 18:12:57

在开发UWP应用程序时,我最近发现相当多的内存泄漏使我的页面无法被GC收集。我的页面上有一个ContentPresenter:

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

当我删除了Content,或者用动态{Binding}替换它之后——当我从它导航时,页面被收集。否则它将留在内存中。是bug还是我做错了什么?有没有一种方法可以释放和清除所有的导航绑定?

更新:正如这里所述,这似乎是微软内部已知的问题。但就我自己的测试/应用程序使用情况而言,x:Bind保存的数据在一段时间后仍然会被收集,例如,当你导航到相同的页面或创建相同的控件一段时间后。我可以看到新的对象被创建了,但是旧的对象在某个时候被收集了。

所以对我来说,这似乎不是一个严重的问题,导致内存不足,它只是不允许对象被收集得像动态绑定一样快。

UWP编译绑定x:绑定产生内存泄漏

由于这个问题,我在Microsoft connect上创建了一个bug。

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

解决这个问题的方法是在页面卸载事件处理程序中显式调用Bindings.StopTracking()。这是因为编译绑定不使用"弱事件"模式,而是直接订阅INotifyPropertyChanged的PropertyChanged事件。这是内存泄漏的一个原因。要取消订阅事件,可以调用Bindings.StopTracking()。编译后的绑定代码不会自动调用它。

是的,它确实会导致内存泄漏,您可以使用以下步骤来防止:

  1. 使用像UnityContainer这样的IoC,创建ViewModel或viewcontainercontrollifetime
  2. 一旦你离开UI,在xaml.cs中给ViewModel属性赋null。