Silverlight+MVVM+Bindings=内存泄漏?到目前为止,我的测试表明,在Silverlight中利用MVVM模式的所有标准方法、示例和框架都存在一个巨大的问题:大量内存泄漏会阻止VM被垃圾收集。显然,这是一个巨大而荒谬的声明-所以我期望有人会理解我出错的原因和位置:)重现的步骤很简单:这创建了一个从根BindingExpression延伸到视图模型的引用链。然后,您可以从UI树中删除视图和对VM的所有引用-但由于根BindingExpressionVM引用链,VM永远不会被垃圾回收。我创建了两个示例来说明问题。他们有一个创建新视图/视图模型的按钮(应该转储对旧视图的所有引用)和一个强制垃圾收集和报告当前内存使用情况的按钮。示例1是超级剥离的校准微型示例。示例2没有使用框架,它只是用我能想到的最简单的方式来说明问题。示例1示例2对于那些可能想要帮助但不想下载示例项目的人,这里是代码2的代码。我们从一个名为FooViewModel的视图模型开始:publicclassFooViewModel:INotifyPropertyChanged{string_fooText;公共字符串FooText{获取{返回_fooText;}设置{_fooText=值;NotifyPropertyChanged("FooText");}}私人字节[]_data;publicFooViewModel(){_data=newbyte[10485760];//用完10mb的内存}}公共事件PropertyChangedEventHandlerPropertyChanged;它只是暴露了一个名为FooText的字符串属性,我们也将绑定到它。INotifyPropertyChanged是促进绑定所必需的。然后我们有一个名为FooView的视图,它是一个用户控件,其中包含:(为简洁起见省略了命名空间)这里重要的一点是绑定到FooText属性的文本框。当然,我们需要设置数据上下文,我选择在代码隐藏中进行,而不是引入ViewModelLocator:this.DataContext=newFooViewModel();MainPage看起来像这样:在后面的代码中有以下内容:privatevoidButton_Click(objectsender,RoutedEventArgse){myContent.Content=newFooView();}privatevoidButton2_Click(objectsender,RoutedEventArgse){MessageBox.Show("收集后使用的内存:"+(GC.GetTotalMemory(true)/1024/1024).ToString()+"MB");注意:要重现该问题,请务必在文本框中键入我认为需要的内容未创建绑定表达式。值得注意的是,这篇知识库文章可能相关,但我不相信,因为“方法2”的解决方法似乎没有效果,而且参考链似乎不匹配。另外,我不确定这是否重要,但我使用CLRProfiler来诊断原因。更新:如果有人想对其进行测试,并在评论中报告他们的发现,我将在此处通过Dropbox托管silverlight应用程序:托管示例。要重现:点击顶部按钮,键入,按下顶部按钮,键入,按下顶部按钮。然后按下按钮。如果它报告10MB的使用量(或其他未增加的量),那么您没有遇到内存泄漏。到目前为止,这个问题似乎发生在我们所有的开发机器上,这些机器是ThinkPadw510s(43192RU),12GBRam,64位Win7Enterprise。这包括一些没有安装开发工具的。值得注意的是,他们正在运行VMWareWorkstation。这个问题似乎没有发生在我试过的其他机器上——包括办公室里的几台家用电脑和其他电脑。我们排除了SL版本、内存量和vmware。还没找到原因。尚未找到解决方案,但现在已确定问题所在。如果由于以下原因调用Silverlight的自动化系统,则会发生此行为:更多信息请参见:http://www.wintellect.com/cs/blogs/sloscialo/archive/2011/04/13/silverlight-memory-leaks-and-automationpeers.aspx因此出现了一个新问题:我们如何禁用自动化节点或以其他方式正确清理它们?这篇文章说明了一种方法:WPFUserControlMemoryLeak然而,这并不是一个真正可行的解决方案,因为我们必须覆盖我们计划使用绑定的每个silverlight控件,更不用说复杂控件的控件模板了。如果有人能找到好的解决方案,我会更改我的答案,但现在似乎没有...编辑:这是一个不错的小解决方案,似乎可以完成这项工作。只需在定义silverlight对象的HTML中添加以下参数:在“无窗口”模式下运行的副作用是自动化不起作用:)第二个示例中没有内存泄漏。使用myContent.Content=newFooView();将FooView的新实例影响到ContentControlmyContent.Content=newFooView();,不再使用引用整个View+ViewModel对象图。最终,它会在需要时收集垃圾。也许您应该澄清是什么让您认为存在内存泄漏(即统计数据、重复步骤等)。以上就是C#学习教程:Silverlight+MVVM+Bindings=memoryleak?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
