c# – ReactiveUI绑定似乎阻止垃圾回收发生

c# – ReactiveUI绑定似乎阻止垃圾回收发生,第1张

概述我们正在使用ReactiveUI帮助构建一个相当大的基于 WPF的 Windows应用程序.一切顺利,直到我们发现我们的应用程序正在消耗大量的内存…基本上我们所有的观点,视图模型和模型都没有被垃圾回收. 基于内存分析器的信息,如Jet Brains dotMemory,ReactiveUI似乎是主要的祸根.特别是我们在我们的视图中配置的ReactiveUI绑定,即使我们使用最佳实践,并确保在视图被 我们正在使用ReactiveUI帮助构建一个相当大的基于 WPF的 Windows应用程序.一切顺利,直到我们发现我们的应用程序正在消耗大量的内存…基本上我们所有的观点,视图模型和模型都没有被垃圾回收.

基于内存分析器的信息,如Jet Brains dotMemory,ReactiveUI似乎是主要的祸根.特别是我们在我们的视图中配置的ReactiveUI绑定,即使我们使用最佳实践,并确保在视图被禁用时所有绑定都被处理.

以下是我们正在创建的其中一个视图的示例.任何关于我们可能会出错的想法将不胜感激.

public partial class RunbookinputsVIEw : IVIEwFor<Runbookinputsviewmodel>{    public static Readonly DependencyProperty viewmodelProperty = DependencyProperty.Register(        "viewmodel",typeof(Runbookinputsviewmodel),typeof(RunbookinputsVIEw));    public RunbookinputsVIEw()    {        InitializeComponent();        this.WhenActivated(d =>        {            d(this.OneWayBind(viewmodel,vm => vm.Addinput,v => v.Addinput.Command));                            d(this.OneWayBind(viewmodel,vm => vm.inputs,v => v.inputs.ItemsSource));        });    }    object IVIEwFor.viewmodel    {        get { return viewmodel; }        set { viewmodel = (Runbookinputsviewmodel)value; }    }    public Runbookinputsviewmodel viewmodel    {        get { return (Runbookinputsviewmodel) GetValue(viewmodelProperty); }        set { SetValue(viewmodelProperty,value); }    }}
解决方法 从这个问题来看,很难说泄漏来自哪里.让泄漏发生一段时间,然后附加到windbg( Debugging Tools For Windows的一部分)的过程(注意:您可能需要构建x86或x64才能使其工作.)

一旦附加,通过输入命令设置.net调试:

.symfixsxe clrsxd av.loadby sos clr

然后可以使用!dumpheap -stat来获取每种类型的内存使用情况.这产生以下格式的输出:(我截断了类名,列表中的可读性).

0:012> !dumpheap -statStatistics:              MT    Count    TotalSize Class name000007fefa55d2e8        1           24 System.[...]TransportSinkProvIDer000007fefa55ce08        1           24 System.Run[...]rtSinkProvIDer000007fee7c32df0        1           24 System.LocalDataStoreHolder000007fee7c2ff78        1           24 System.Colle[...]000007fee7c2ece0        1           24 System.Resources.FastResourceComparer000007fee7c2ead0        1           24 System.Resources.ManifestBasedResourcegroveler000007fee7c2ea70        1           24 System.[...]eManagerMediator000007fee4cc1b70        4         1216 System.Xml.Xmldocument

如果您有内存泄漏,那么您将看到泄漏的对象. (应该有很多它们).一旦你确定了什么泄漏,你可以做一个!dumpheap -type来获取一个实际对象的列表. (对于本例,我将使用System.Xml.Xmldocument.类型名称区分大小写,必须是完全限定的.)

0:012> !dumpheap -type System.Xml.Xmldocument         Address               MT     Size0000000002af9050 000007fee4cc1b70      304     0000000002afa628 000007fee4cc1b70      304     0000000002b0ea30 000007fee4cc1b70      304     00000000037e2780 000007fee4cc1b70      304     Statistics:              MT    Count    TotalSize Class name000007fee4cc1b70        4         1216 System.Xml.Xmldocument

您的列表可能会更大,但是概率表示泄漏类型的任何随机实例将是您感兴趣的事情.如果我们在其中一个地址上执行 *** 作,我们将获得类似于此的输出:

0:012> !do 2af9050name:        System.Xml.XmldocumentMethodtable: 000007fee4cc1b70EEClass:     000007fee4ae7f00Size:        304(0x130) bytesfile:        C:\windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dllFIElds:              MT    FIEld   Offset                 Type VT     Attr            Value name000007fee4cc2b40  40004fc        8   System.Xml.XmlNode  0 instance 0000000000000000 parentNode000007fee4cc2258  400050a       10 ...Xmlimplementation  0 instance 0000000002af9180 implementation000007fee4cc22f0  400050b       18 ....Xml.Domnametable  0 instance 0000000002af92e0 domnametable[EntrIEs removed for clarity]000007fee4cc26f0  400052f      108 ...m.Xml.XmlResolver  0 instance 0000000000000000 resolver000007fee7c18c48  4000530      126       System.Boolean  1 instance                0 bSetResolver000007fee7c113e8  4000531      110        System.Object  0 instance 0000000002af9788 objLock000007fee4cc11b0  4000532      118 ....Xml.XmlAttribute  0 instance 0000000000000000 namespaceXml

您可以对表中列出的任何对象使用!做更多的信息.类似System.String和System.Boolean将会吐出它们的实际值.如果从创建的对象不清楚,下一步可能是使用!gcroot -nostacks来查找对象的引用.

0:012> !gcroot -nostacks 2af9050Handletable:    00000000006117d8 (pinned handle)    -> 0000000012a55748 System.Object[]    -> 0000000002af9050 System.Xml.XmldocumentFound 1 unique roots (run '!GCRoot -all' to see all roots).

有更多的命令,这已经太长了. !help命令提供了一个很好的列表. (要使用任何一个,您需要在命令前缀!!!help [command]提供有关特定命令的详细信息,例如!help dumpobj:

0:012> !help dumpobj-------------------------------------------------------------------------------!DumpObj [-nofIElds] <object address>This command allows you to examine the fIElds of an object,as well as learn important propertIEs of the object such as the EEClass,the Methodtable,and the size.You might find an object pointer by running !DumpStackObjects and choosingfrom the resultant List. Here is a simple object:    0:000> !DumpObj a79d40    name: Customer    Methodtable: 009038ec    EEClass: 03ee1b84    Size: 20(0x14) bytes     (C:\pub\unittest.exe)    FIElds:          MT    FIEld   Offset                 Type  VT     Attr    Value name    009038ec  4000008        4             Customer   0 instance 00a79ce4 name    009038ec  4000009        8                 Bank   0 instance 00a79d2c bankNote that fIElds of type Customer and Bank are themselves objects,and you can run !DumpObj on them too. You Could look at the fIEld directly in memory usingthe offset given. "dd a79d40+8 l1" would allow you to look at the bank fIEld directly. Be careful about using this to set memory breakpoints,since objectscan move around in the garbage collected heap.What else can you do with an object? You might run !GCRoot,to determine what roots are keePing it alive. Or you can find all objects of that type with "!DumpHeap -type Customer".The column VT contains the value 1 if the fIEld is a valuetype structure,and0 if the fIEld contains a pointer to another object. For valuetypes,you can take the Methodtable pointer in the MT column,and the Value and pass them to the command !DumpVC.The abbreviation !do can be used for brevity.The arguments in detail:-nofIElds:     do not print fIElds of the object,useful for objects like                   String
总结

以上是内存溢出为你收集整理的c# – ReactiveUI绑定似乎阻止垃圾回收发生全部内容,希望文章能够帮你解决c# – ReactiveUI绑定似乎阻止垃圾回收发生所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1260440.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-08
下一篇2022-06-08

发表评论

登录后才能评论

评论列表(0条)

    保存