Original post: http://www.telerik.com/community/forums/wpf/chart/radchart-memory-usage-grows-after-regularly-using-radchart-rebind.aspx
Unable to read: I think chrome sent in some odd formatting
I have a solution that consists of a windows form application with an instance of a custom WPF control (within System.Windows.Forms.Integration.ElementHost).
The WPF control contains an instance of the WPF RadChart; its purpose is to host the RadChart and provide helper methods for interpreting a supplied configuration, defining data series, color paletts etc and initialize databinding to a custom data type.
The MVVM technique is used to give each pointmark a particular fill color based on the YValue (implementing INotifyPropertyChanged and so on).
<
ControlTemplate
TargetType
=
"telerikCharting:PointMark"
>
...
Fill="{Binding Path=DataItem.PointMarkColor}"
...
The intent is for uses to run the application normally (interacting with various data-handing forms) and for the application to be deployed on a monitoring workstation, displaying data updates on a flatscreen.
The problem is that there appears to be a memory leak of some kind. I've hunted this down to the point where the new data is updated to the chart.
Firstly, althrough databound, updates to the XValue and YValue of MyData is not made visible to the ViewModel or the Chart via INotifyPropertyChanged. Only a change to 'MyData.ValueStatus' property triggers PropertyChanged (which in turn updates the MyDataViewModel.PointMarkColor).
This was done by design; a specific data result amounts to about 1300 datapoints which are updated at the *same time* and we've found response is faster if we simply update the data soure and rebind the RadChart as opposed to having the chart update each of its 1300 databound points through INotifyPropertyChanged.
I know viewing memory usage within task manager isnt really accurate but the eventual result is clear enough:
The application starts at 110MB and very slowly climbs in resources; a 12-hour run came to 900MB and still climbing.
Running the application (binding the initial data upon load) and omiting any re-binding statement (the in-memory data source is still updated): the application hovers around 100MB to 110=112MB.
Strange thing: minimizing the window drops the usage to 30MB (not actually released, just paged memory i know) but opening the window again from a minimized state puts the Mem usage to about 50MB, and it slowly starts climbing again from there (minimizing and re-opening restarts this process).
I suspect there's not an actual data mem leak as such but there's some form of WPF presenation cache that's being added to when Rebinding to the RadChart; maybe a RePaint/Draw or something.
Is there a way to clear this or avoid it? At this stage, keeping the windows form open (with elementHost containing custom WPF control with RadChart) will eventually consume a monitoring workstation and slowly sip at a user's resources.
Below is a code example from the WPFControl of how i'm initializing and binding data to the chart:
public
void
DefineDataSeries(List<MySeriesConfiguration> series,
bool
zoomEnabled)
{
if
(zoomEnabled)
{
RadChartMain.DefaultView.ChartArea.ZoomScrollSettingsX.ScrollMode = ScrollMode.ScrollAndZoom;
}
else
{
RadChartMain.DefaultView.ChartArea.ZoomScrollSettingsX.ScrollMode = ScrollMode.None;
}
RadChartMain.PaletteBrushes.Clear();
RadChartMain.SeriesMappings.Clear();
for
(
int
i = 0; i < series.Count; i++)
{
//Add color to pallet
RadChartMain.PaletteBrushes.Add(
new
SolidColorBrush(series[i].Definition.TrendSeriesColor));
//Note: HelperClass.GetSeriesMapping uses the i for the seriesMapping.CollectionIndex
SeriesMapping seriesmapping = HelperClass.GetSeriesMapping(series[i], i);
//Create mapping and add to radChart
RadChartMain.SeriesMappings.Add(seriesmapping);
}
RadChartMain.PaletteBrushesRepeat =
true
;
}
//This method gets called from the WinForms application after the data is updated.
public
void
Rebind(ObservableCollection<ObservableCollection<MyDataViewModel>> chartData)
{
RadChartMain.ItemsSource =
this
.ChartData;
RadChartMain.Rebind();
}