我有一个使用MVVM
设计模式的WPF应用。
在测试内存增长时,我遇到了内存泄漏。我已经尝试修复了好几天没有成功。如果可能的话,有人可以指出问题所在。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="5"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<!--Service Header Editable Data-->
<StackPanel Grid.Row="0">
</StackPanel>
<telerik:RadGridView x:Name="grid"
IsReadOnly="{Binding IsServiceReadOnly}"
ItemsSource="{Binding DetailsModel.Collection}"
SelectedItem="{Binding SelectedCharge, Mode=TwoWay}"
CellEditEnded="grid_CellEditEnded"
AutoGenerateColumns="False"
ShowGroupPanel="False"
RowIndicatorVisibility="Collapsed"
ShowColumnFooters="True"
CanUserFreezeColumns="False"
behav:GridFoucsBehav.GridFocusPosition="{Binding GridViewChargesFocColPos, Mode=TwoWay}">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn Header="{lp:Lp UI:ServiceCode}"
DataMemberBinding="{Binding ServiceCode}">
<telerik:GridViewDataColumn.AggregateFunctions>
<telerik:CountFunction Caption="c: " />
</telerik:GridViewDataColumn.AggregateFunctions>
<telerik:GridViewDataColumn.CellEditTemplate>
<DataTemplate>
<CustomControl:MyControl
SelectedIDPath="ID"
SelectedID="{Binding ServiceID}"
StringToSearch="{Binding ServiceCode}"
SelectedItem="{Binding DataContext.SelectedService, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type v:MyView}}}"
ExprQueryByString="{Binding DataContext.ServiceExprQueryByString, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type v:MyView}}}">
<CustomControl:Lookup.DisplayMemberPaths>
<s:String>code</s:String>
</CustomControl:Lookup.DisplayMemberPaths>
<CustomControl:Lookup.ColumnHeaders>
<s:String>Code</s:String>
<s:String>Description</s:String>
</CustomControl:Lookup.ColumnHeaders>
</CustomControl:MyControl>
</DataTemplate>
</telerik:GridViewDataColumn.CellEditTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn Header="{lp:Lp UI:ReceiptView_NumberOfUnit}"
DataMemberBinding="{Binding NumberOfUnit}">
<telerik:GridViewDataColumn.CellEditTemplate>
<DataTemplate>
<telerik:RadNumericUpDown Value="{Binding NumberOfUnit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
UpdateValueEvent="PropertyChanged"
Minimum="0" />
</DataTemplate>
</telerik:GridViewDataColumn.CellEditTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn Header="{lp:Lp UI:Code}"
DataMemberBinding="{Binding Code, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<telerik:GridViewDataColumn.CellEditTemplate>
<DataTemplate>
<TextBox Text="{util:TwoWayBinding Code}" />
</DataTemplate>
</telerik:GridViewDataColumn.CellEditTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn Header="{lp:lp UI:Remarks}"
DataMemberBinding="{Binding Remarks,Mode=TwoWay}">
<telerik:GridViewDataColumn.CellEditTemplate>
<DataTemplate>
<TextBox Text="{Binding Remarks, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</telerik:GridViewDataColumn.CellEditTemplate>
</telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</Grid>
在打开几个窗口并关闭它们之后,内存增加,并且对象仍然挂在内存中。
这是我的窗户:
MyWindow System.Windows.DataTemplate-> MyApp.MyWindow->(System.Windows.Controls.Border,System.Windows.EffectiveValueEntry [],System.Windows.Threading.Dispatcher,...):12 MB(11.23%)(3 对象,852个字节(0.00%))以前的分配(最新到 最旧):11 MB(11.22%),7.4 MB(7.19%),7.4 MB
(7.19%),引用者:12 MB(11.23%) 从System.Windows.DataTemplate获得System.Windows.EffectiveValueEntry []-> System.Windows.DataTemplate->(MyWindow,System.Collections.Specialized.HybridDictionary,System.Windows.Threading.Dispatcher,...)
指的是:668 kB(0.64%) 到Telerik.Windows.Controls.RadTabControl MyWindow-> Telerik.Windows.Controls.RadTabControl->(System.Windows.EffectiveValueEntry [],System.Windows.Style,System.Windows.Threading.Dispatcher,...)93 kB(0.09%) 到MyApp.ItemsNavigator MyApp.MyWindow-> MyApp.ItemsNavigator->(System.Windows.Controls.DockPanel,System.Windows.Threading.Dispatcher,Telerik.Windows.Controls.RadTabItem,...) 24 kB(0.02%) 到Telerik.Windows.Controls.RadContextMenu MyApp.MyWindow-> Telerik.Windows.Controls.RadContextMenu->((System.Windows.Controls.ControlTemplate,System.Windows.EffectiveValueEntry [],System.Windows.Threading.Dispatcher,...) 2.8 kB(0.00%)至System.Windows.Controls.Border MyApp.MyWindow-> System.Windows.Controls.Border->((MyApp.MyWindow,System.Windows.EffectiveValueEntry [],System.Windows.Threading.Dispatcher) 3.3 MB(3.26%)到MyApp.LocalizedValidationPanel MyApp.MyWindow-> MyApp.LocalizedValidationPanel->(System.Windows.Controls.ContentPresenter,System.Windows.Controls.Grid,System.Windows.Threading.Dispatcher,...) 3.0 MB(2.97%)到MyApp.ExRadGridView MyApp.MyWindow-> MyApp.ExRadGridView->(System.Windows.EffectiveValueEntry [],System.Windows.Style,System.Windows.Threading.Dispatcher,...) 2.2 MB(2.14%)到Telerik.Windows.Controls.RadGridView MyApp.MyWindow-> Telerik.Windows.Controls.RadGridView->(System.Windows.EffectiveValueEntry [],System.Windows.Style,System.Windows.Threading.Dispatcher,...) 1.1 MB(1.06%)到MyApp.MenuItem MyApp.MyWindow-> MyApp.MenuItem->(System.Windows.EffectiveValueEntry [],System.Windows.Style,System.Windows.Threading.Dispatcher,...) 到System.Windows.EffectiveValueEntry 1.1 MB(1.04%)[] MyApp.MyWindow-> System.Windows.EffectiveValueEntry []->(System.Collections.Hashtable,System.Uri,System.Windows.EventHandlersStore,...)
我明白了。如果有帮助的话
如您在最后一个细节中所注意到的,Telerik.Windows.Controls.RadGridView System.Collections.Generic.Dictionary.Entry []-> Telerik.Windows.Controls.RadGridView->((System.Windows.EffectiveValueEntry [],System.Windows.Style,System.Windows.Threading.Dispatcher,...):12 MB(100.00%)(3个对象,0.0个字节(0.00%))
引用者:12 MB(100.00%) 来自System.Collections.Generic.Dictionary.Entry [] System.Collections.Generic.Dictionary-> System.Collections.Generic.Dictionary.Entry []->(Telerik.Windows.Controls.RadGridView)
指的是:12 kB(0.10%) 到System.Windows.EffectiveValueEntry [] Telerik.Windows.Controls.RadGridView-> System.Windows.EffectiveValueEntry []->(MS.Utility.FrugalMap,System.Boolean,System.Windows.EventHandlersStore,...) 8.0 KB(0.07%)至Telerik.Windows.Data.DataItemCollection Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Data.DataItemCollection->(Telerik.Windows.Data.CompositeFilterDescriptorCollection,Telerik.Windows.Data.GroupDescriptorCollection,Telerik .Windows.Data.ObservableCollectionManagerCollection,...) 3.5 kB(0.03%)到System.Windows.Controls.Grid Telerik.Windows.Controls.RadGridView-> System.Windows.Controls.Grid->(System.Windows.Controls.UIElementCollection,System.Windows.EffectiveValueEntry [],System.Windows.Threading.Dispatcher) 1.0 kB(0.01%)至Telerik.Windows.Controls.GridView.Selection.GridViewItemSelectionHandler Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.Selection.GridViewItemSelectionHandler->(Telerik.Windows.Controls.RadGridView,Telerik .Windows.Data.DataItemCollection,Telerik.Windows.Data.Selection.InternalSelectionItemsStorage) 912字节(0.01%) 到Telerik.Windows.Controls.GridView.Selection.SelectionDrag Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.Selection.SelectionDrag->(Telerik.Windows.Controls.GridView.Scrolling.ScrollViewerCoordinator,Telerik.Windows .Controls.GridView.Selection.DefaultMouseInfoProvider,Telerik.Windows.Controls.RadGridView) 564字节(0.00%) 到Telerik.Windows.Controls.GridView.GridViewItemContainerGenerator Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.GridViewItemContainerGenerator->(System.Collections.Generic.Queue,Telerik.Windows.Controls.GridView.GridViewItemContainerGenerator.ItemBlock ,Telerik.Windows.Controls.RadGridView) 504字节(0.00%) 到Telerik.Windows.Controls.GridView.Selection.CellSelectionHandler Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.Selection.CellSelectionHandler->(Telerik.Windows.Controls.GridView.Selection.CellInfoCollection,Telerik.Windows .Controls.RadGridView) 504字节(0.00%) 到Telerik.Windows.Controls.GridView.DetailsProvider Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.DetailsProvider->(System.Action,System.Func) 360字节(0.00%) 到System.Globalization.CultureInfo Telerik.Windows.Controls.RadGridView-> System.Globalization.CultureInfo->(System.Globalization.TextInfo,System.String) 288字节(0.00%) 到Telerik.Windows.Data.AggregateResultCollection Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Data.AggregateResultCollection->(System.Collections.Generic.List) 288字节(0.00%) 到System.Collections.ObjectModel.ObservableCollection Telerik.Windows.Controls.RadGridView-> System.Collections.ObjectModel.ObservableCollection->(System.Collections.Generic.List,System.Collections.ObjectModel.ObservableCollection.SimpleMonitor) 240字节(0.00%) 到System.Collections.Generic.HashSet Telerik.Windows.Controls.RadGridView-> System.Collections.Generic.HashSet->(System.Collections.Generic.ObjectEqualityComparer) 228字节(0.00%) 到System.EventHandler Telerik.Windows.Controls.RadGridView-> System.EventHandler->(Behaviors.AlignGridViewCellBehav) 216字节(0.00%) 到Telerik.Windows.Controls.GridView.ItemDataCellPresenterHeightStorage Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.ItemDataCellPresenterHeightStorage->(System.Collections.Generic.Dictionary) 192字节(0.00%) 到Telerik.Windows.Controls.GridView.Selection.CellAndRowSelectionDispatcher Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.Selection.CellAndRowSelectionDispatcher->(System.Func,Telerik.Windows.Controls.GridView.KeyboardModifiersProvider) 192字节(0.00%) 到System.Collections.ObjectModel.ObservableCollection Telerik.Windows.Controls.RadGridView-> System.Collections.ObjectModel.ObservableCollection->(System.Collections.Generic.List) 180个字节(0.00%) 到Telerik.Windows.Controls.GridView.ItemAttachedStorage Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.ItemAttachedStorage->(System.Collections.Generic.Dictionary) 72个字节(0.00%) 到System.Collections.Generic.List Telerik.Windows.Controls.RadGridView-> System.Collections.Generic.List->(System.Action [])36个字节(0.00%) 到Telerik.Windows.Controls.GridView.Selection.CompositeSelectionHandler Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.Selection.CompositeSelectionHandler->(Telerik.Windows.Controls.RadGridView) 36个字节(0.00%) 到Telerik.Windows.Controls.GridView.DefaultCellLocator Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridView.DefaultCellLocator->(Telerik.Windows.Controls.RadGridView) 12 MB(99.74%) 到Telerik.Windows.Controls.GridViewColumnCollectionInternal Telerik.Windows.Controls.RadGridView-> Telerik.Windows.Controls.GridViewColumnCollectionInternal->(System.Collections.Generic.List,System.Collections.Generic.List,System.Collections.ObjectModel.ObservableCollection .SimpleMonitor,...)
在打开窗口并关闭3次后,它显示3 objects
。
我花了很长时间试图弄清楚发生了什么,但是我不知道。我使用RadGridView
和几乎相同的控件在不同的屏幕上工作,没有问题。我错过了什么吗?
如果您需要更多详细信息,请告诉我
仅供参考:当RadGridView被注释掉时,没有问题
编辑 添加另一个内存跟踪
MS.Internal.ComponentModel.DependencyObjectPropertyDescriptor System.Collections.Generic.Dictionary.Entry []-> MS.Internal.ComponentModel.DependencyObjectPropertyDescriptor->(System.Object,System.String,System.Windows.DependencyProperty,...):12 MB(100.00%)
引自:
的12 MB(100.00%)参考:12 MB(100.00%) 到System.Collections.Generic.Dictionary MS.Internal.ComponentModel.DependencyObjectPropertyDescriptor-> System.Collections.Generic.Dictionary->(System.Collections.Generic.ObjectEqualityComparer,System.Int32 [])
我相信这是问题所在,但我不是导致使用属性描述符的原因。
答案 0 :(得分:1)
已经调查了几个月,并且与WPF有关。
WPF的垃圾收集器确实很复杂,它在不再需要数据后才释放数据。问题是,它并不真正知道何时将不再需要某些组件。
CellEditEnded="grid_CellEditEnded"
您是否正在关闭窗口时取消订阅此事件?在某些时候它将被垃圾回收器取消订阅,但是在关闭时刻,它可能仍在内存中。这只是一个例子。开发人员的一般建议是“如果您可以取消订阅事件,那么当不再需要它时,请去做”,否则它们在内存中的存在会延长。
我的应用仍然存在内存泄漏。通常,我使用RadTabControl来显示数据,但是在关闭选项卡后,我仍然有未释放的内存(5-10 MB),该内存最终会在一段时间后释放。
我建议您做的是检查this article并使用出色的内存分析工具(Jet Brains很棒),因为它们可以告诉您正在占用内存而不释放内存的内容,是指您的代码,功能和/或应用程序的VisualTree。我也建议您阅读这篇简短的文章:
最后,我想补充一点,根据我的经验,您将无法防止所有内存泄漏。