使用telerik:RadGridView:内存泄漏

时间:2018-08-07 09:27:46

标签: wpf memory-leaks telerik telerik-grid

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

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

1 个答案:

答案 0 :(得分:1)

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

WPF的垃圾收集器确实很复杂,它在不再需要数据后才释放数据。问题是,它并不真正知道何时将不再需要某些组件。

 CellEditEnded="grid_CellEditEnded"

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

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

我建议您做的是检查this article并使用出色的内存分析工具(Jet Brains很棒),因为它们可以告诉您正在占用内存而不释放内存的内容,是指您的代码,功能和/或应用程序的VisualTree。我也建议您阅读这篇简短的文章:

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

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