在我的一个wp8应用程序中,我使用BindingReflector来启用对转换器参数的绑定。我遇到的一个问题是,任何高于(在XAML中)使用参数绑定的转换器的转换器根本不会得到GC。我注意到使用这种特定顺序的页面在导航到它然后返回并重复时会获得越来越多的内存。
经过这么多尝试来计算正在发生的事情后,我决定尝试改变他们在XAML中的顺序,使得在顶部使用反射器并且问题得到解决。我想知道是否有人可以对此有任何解释。
当我遇到这个内存泄漏问题时, GC Roots 下的分析器显示我的转换器都使用带有 Handle的反射器(不是直接)引用转换器( WeakRef)即可。不知道怎么会发生这种情况,但现在一旦他们吼叫,一切都很好并且正确地进行了GC。
注意转换器都在兄弟控件中,结构基本上是这样的列表框:
<ListBox ItemsSource={Binding...}>
<!-- ... item template like below -->
<controlX propX={Binding xxx, converter=....}/>
<controlY propY={Binding yyy, converter=....}/>
...
</ListBox>
修改 我创建并上传了一个简单的测试项目,您可以download the zip from here。 运行应用程序,一旦MainPage加载,单击将您带到Page1.xaml的按钮,点击后退按钮,然后单击再次转到Page1.xaml的按钮,重复此过程。
我在每个页面的标题下都包含了显示当前内存使用情况的计数器,你不会注意到任何东西,但接下来的3个计数器是
你会注意到黄色和绿色从不超过3,当你在MainPage.xaml和Page1.xaml之间往返时,红色会继续上升。
现在,使用Page1.xaml中的转换器切换2个按钮控件的位置,只需将它们注释掉,然后取消注释它们,你就会发现所有3个计数器都不会超过3个。
编辑2: 显然这不仅仅是绑定反射器。让两个按钮使用相同的转换器将导致特定的转换器实例不是GC。我不知道为什么会发生这种情况..
答案 0 :(得分:2)
到目前为止我发现了什么:
解决方法:
我有胆量感觉泄漏来自DataTemplate中的一个对象,该对象已经从模板范围之外声明(在您的情况下,转换器,但它也让我想起that similar leak involving an attached property) 。在寻找在同一范围内声明转换器的方法时,我设法找到了一种解决方法:
坐下,深呼吸。打开漏转换器的类(在您的情况下,RandomConverter
)。使其继承FrameworkElement
形式。泄漏固定。
......不要问。
这种解决方法实际上很好地找出了内存分配问题所在。我会在接下来的几天里尝试进一步挖掘,但不要期望太多。