使用telerik:RadGridView:内存泄漏



我有一个使用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>

在打开几个窗口并关闭它们之后,内存会增长,对象仍然挂在内存中。

这是给我的窗口的:

MyWindowSystem.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.Window.Controls-RadTabControl->(System.Windows.EffectiveValueEntry[],System.Windows.Style,System.Windows.Threading.Dispatcher,…)93kB(0.09%)到MyApp.ItemsNavigator MyApp.MyWindow->MyApp.IitemsNavigator->(System.Windows.Controls.DockPanel、System.Windows.Threading.Dispatcher、Telerik.Windows.Controls.RadTabItem,…)24 kB(0.02%)至Telerik.Windows.Controls.RadContextMenu MyApp.MyWindow->Telerik.Window.Controls.RadContextMenu->(System.Windows.Control.ControlTemplate,System.Windows.EffectiveValueEntry[],System.Windows.Threading.Dispatcher,…)2.8 kB(0.00%)到System.Windows.Controls.Border MyApp.MyWindow->System.Windows.CControls.Border->(MyApp.MyMyWindow,System.Windows.EffectiveValueEntry[],System.Windows.Threading.Dispatcher)3.3 MB(3.26%)到MyApp.LocalizedValidationPanel MyApp.MyWindow->MyApp.LLocalizedValidationPanel->(System.Windows.Controls.ContentPresenter、System.Windows.Cntrols.Grid、System.Windows.Threading.Dispatcher…)3.0 MB(2.97%)到MyApp.ExRadGridView MyApp.MyWindow->MyApp.ExCRadGridView->(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.ManupItem->(System.Windows.EffectiveValueEntry[],System.Windows.Style,System.Windows.Threading.Dispatcher,…)1.1 MB(1.04%)到System.Windows.EffectiveValueEntry[]MyApp.MyWindow->System.Windows.EeffectiveValueEntry[]->(System.Collections.Hashtable,System.Uri,System.Windows.EventHandlersStore,…)

我明白了。如果能对有所帮助

Telerik.Windows.Controls.RadGridViewSystem.Collections.Generic.Dictionary.Entry[]->Telerik.Windows.Controls.RadGridView->(System.Windows.EffectiveValueEntry[],System.Windows.Style,System.Windows.Threading.Dispatcher,…):12MB(100.00%)(3个对象,0.0字节(0.00%))

引用者:12 MB(100.00%)来自System.Collections.Generic.Dictionary.Entry[]System.Collections.Generic.Dictionary->System.Collections.General.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.Window.Data.DataItemCollection Telerik.Windows.Controls.RadGridView->Telerik.Windows.Data.DetaItemCollection->3.5 kB(0.03%)到System.Windows.Controls.Grid Telerik.Windows.Controls.RadGridView->System.Windows.Cntrols.Grid->(System.Windows.Collections.UIElementCollection,System.Windows.EffectiveValueEntry[],System.Windows.Threading.Dispatcher)1.0 kB(0.01%)到Telerik.Windows.Controls.GridView.Selection.GridViewItemSelectionHandler Telerik.Window.Controls.RadGridView->Telerik.Windows.Controls.GridView.Selections.GridViewItemsSelectionHandler->912字节(0.01%)到Telerik.Windows.Controls.GridView.Selection.SelectionDrag Telerik.Windows.Controls.RadGridView->Telerik.indows.Controls.GridView.Selection拖动->(Telerik.Window.Controls.FridView.SScrolling.SScrollViewerCoordinator,Telerik.Windows7.Controls.GridView.Section.DefaultMouseInfoProvider,Telerik.Windows.Controls.RadGridView)564字节(0.00%)至Telerik.Windows.Controls.GridView.GridViewItemContainerGenerator Telerik.Window.Controls.RadGridView->Telerik.Windows.Controls.GridViewItemContainerGenerator->(System.Collections.Generic.Queue,Telerik.indows.Controls.GridView.GridViewItemContainerGenerator.ItemBlock,Telerik.Windows.Controls.RadGridView)504字节(0.00%)至Telerik.Windows.Controls.GridView.Selection.CellSelectionHandler Telerik.Window.Controls.RadGridView->Telerik.Windows.Controls.GridView.Selections.CellSelection Handler->504字节(0.00%)至Telerik.Windows.Controls.GridView.DetailsProvider Telerik.Windows.Controls.RadGridView->Telerik.indows.Controls.GridView.DetailesProvider->(System.Action,System.Func)360字节(0.00%)到System.Globalization.CultureInfo Telerik.Windows.Controls.RadGridView->System.Globalize.CultureInfo->(System.Globalize.TextInfo,System.String)288字节(0.00%)到Telerik.Windows.Data.AggregateResultCollection Telerik.Window.Controls.RadGridView->Telerik.Windows.Data.AgregateResultCollection->(System.Collections.Generic.List)288字节(0.00%)到System.Collections.ObjectModel.ObservableCollection Telerik.Windows.Controls.RadGridView->System.Collections.Object Model.ObsservableCollection->(System.Collections.Generic.List,System.Collections.ObjectModel.ObsObservableCollection.SimpleMonitor)240字节(0.00%)到System.Collections.Generic.HashSet Telerik.Windows.Controls.RadGridView->System.Collections.General.HashSet->(System.Collections.泛型.ObjectEqualityComparer)228字节(0.00%)到System.EventHandler Telerik.Windows.Controls.RadGridView->System.EventHandler->(Behaviors.AlignGridViewCellBehav)216字节(0.00%)至Telerik.Windows.Controls.GridView.ItemDataCellPresenterHeightStorage Telerik.Window.Controls.RadGridView->Telerik.Windows.Controls.GridView.IItemDataCellPresenter HeightStorage->(System.Collections.Generic.Dictionary)192字节(0.00%)到Telerik.Windows.Controls.GridView.Selection.CellAndRowSelectionDispatcher Telerik.Window.Controls.RadGridView->Telerik.Windows.Controls.GridView.Selections.CellAndrowSelectionDisptcher->(System.Func,Telerik.Windows7.Controls.FridView.KeyboardModifiersProvider)192字节(0.00%)到System.Collections.ObjectModel.ObservableCollection Telerik.Windows.Controls.RadGridView->System.Collections.ObjectModel.ObsservableCollection->(System.Collections.Generic.List)180字节(0.00%)至Telerik.Windows.Controls.GridView.ItemAttachedStorage Telerik.Window.Controls.RadGridView->Telerik.Windows.Controls.FridView.IItemAttachedStorage->(System.Collections.Generic.Dictionary)72字节(0.00%)到System.Collections.Generic.List Telerik.Windows.Controls.RadGridView->System.Collections.General.List->(System.Action[])36字节(0.00%)至Telerik.Windows.Controls.GridView.Selection.CompositeSelectionHandler Telerik.Windows.Controls.RadGridView->Telerik.indows.Controls.GridView.Selections.CompositySelectionHandler->(Telerik.wink.Controls.RadGridView)36字节(0.00%)至Telerik.Windows.Controls.GridView.DefaultCellLocator Telerik.Window.Controls.RadGridView->Telerik.Windows.Controls.GridView.DDefaultCellLocator->(Telerik.Windows7.Controls.RadGridView)1200万桶(99.74%)到Telerik.Windows.Controls.GridViewColumnCollectionInternal Telerik.Window.Controls.RadGridView->Telerik.Windows.Controls.FridViewColumnCollection Internal->(System.Collections.Generic.List,System.Collections.Generic.List、System.Collections.ObjectModel.ObsObservableCollection.SimpleMonitor,…)

正如您在最后的详细信息中注意到的,它在打开窗口并关闭三次后显示3 objects。我花了很长时间试图弄清楚发生了什么,但我做不到。我用RadGridView和几乎相同的控件在不同的屏幕上工作,没有问题。我错过了什么吗?

如果您需要更多详细信息,请告诉我

仅供参考:当RadGridView被评论掉时,没有问题

编辑添加另一个内存跟踪

MS.Internal.ComponentModel.DependencyObjectPropertyDescriptorSystem.Collections.Generic.Dictionary.Entry[]->MS.Internal.ComponentModel.DependencyObjectPropertyDescriptor->(System.Object,System.String,System.Windows.DependentyProperty,…):12 MB(100.00%)

引用者:中的12 MB(100.00%)

参考:12 MB(100.00%)到System.Collections.Generic.Dictionary MS.Internal.ComponentModel.DependencyObjectPropertyDescriptor->System.Collections.General.Dictionary->(System.Collections.Generic.ObjectEqualityComparer,System.Int32[])

我相信这就是问题所在,但我不知道使用属性描述符的原因。

它已经调查了几个月,与WPF有关。

WPF有一个非常复杂的垃圾回收器,它在不再需要数据后释放数据。问题是,它真的不知道什么时候你就不再需要一些组件了。

CellEditEnded="grid_CellEditEnded"

您是否在关闭窗口的同时取消订阅此活动?在某个时刻,它将被垃圾回收器取消订阅,但在关闭时,它可能仍在内存中。这只是一个例子。开发人员的一般建议是"如果您可以取消订阅事件,当它不再需要时,就去做",否则它们在内存中的存在时间会延长。

我的应用程序仍然存在内存泄漏。通常,我使用RadTabControl来显示数据,但在关闭选项卡后,我仍然有未释放的内存(5-10MB),这是一段时间后最终释放的。

我可以建议你做的是查看这篇文章,并使用很棒的内存分析工具(JetBrains非常棒),因为它们可以告诉你什么是占用内存而不是释放内存,参考你的代码、函数和/或应用程序的VisualTree。我也可以推荐你阅读这篇短文:

https://www.red-gate.com/products/dotnet-development/ants-memory-profiler/learning-memory-management/WPF-silverlight-pitfalls

最后,我想补充一点,根据我的经验,你将无法防止所有的内存泄漏。

最新更新