Pre loader

Memory leak using WPF

Welcome to the SciChart Forums!

  • Please read our Question Asking Guidelines for how to format a good question
  • Some reputation is required to post answers. Get up-voted to avoid the spam filter!
  • We welcome community answers and upvotes. Every Q&A improves SciChart for everyone

WPF Forums | JavaScript Forums | Android Forums | iOS Forums

0
1

I have an MVVM application that is split into several different pages. The Status page includes 2 unique SciChartSurface controls repeated for 16 similar listbox items (for a total of 32 charts on screen at once). Each surface uses a FastLineRenderableSeries and is bound to an XyDataSeries<TimeSpan, double>() property. These charts are at the lowest level of several nested custom UserControl items.

When I run the application, every time I navigate to the Status page, a new SciChartSurface seems to be created. When I navigate away from the Status page, the existing surface does not appear to be removed.

I’m having trouble figuring out just where the memory leak is occurring. I’m not actually disposing of the Status page ViewModel when the user navigates away from it, so I don’t believe it’s caused by not clearing event handlers or anything from the ViewModel side. I think the issue is related to how WPF clears the visual tree — where something in the visual tree is staying alive and then new controls are being drawn as well (effectively creating copies of each chart). I’ve found a similar issue here, but couldn’t find anything similar in my code.

I’ve attached two screenshots of the memory profiler view for the same chart object from the Status page: one after navigating to the Status page 14 times, the other after navigating to the Status page 30 times. From the screenshots, you can see that the number of SciChartSurface objects increases 224 to 480.

Here is the XAML for the lowest level UserControl that displays one of the charts:

<UserControl 
    x:Class="SmslsControl.source.View.Status.ScatteringHistory"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
    xmlns:local="clr-namespace:SmslsControl.source.View"
    mc:Ignorable="d" 
    d:DesignWidth="150" d:DesignHeight="80"
    d:DataContext="{Binding StatusPage.DataCollectorList[0], Source={StaticResource Locator}}">

    <UserControl.Resources>
        <ResourceDictionary Source="../StatusResources.xaml" />
    </UserControl.Resources>

    <!-- Light Scattering History Plot -->
    <s:SciChartSurface Grid.Row="2" s:ThemeManager.Theme="BrightSpark" Padding="0,2" Margin="3">

        <s:SciChartSurface.XAxis>
            <s:TimeSpanAxis AutoRange="Always" Visibility="Collapsed"/>
        </s:SciChartSurface.XAxis>

        <s:SciChartSurface.YAxes>
            <s:NumericAxis Style="{StaticResource YAxisStyle}"/>
        </s:SciChartSurface.YAxes>

        <s:SciChartSurface.RenderableSeries>
            <s:FastLineRenderableSeries 
                DataSeries="{Binding LightScatterHistory}"
                Style="{StaticResource LineSeriesStyle}"/>
        </s:SciChartSurface.RenderableSeries>

        <s:SciChartSurface.ChartModifier >
            <s:ModifierGroup>
                <s:RubberBandXyZoomModifier ExecuteOn="MouseLeftButton" IsAnimated="True"/>
                <s:ZoomExtentsModifier ExecuteOn="MouseDoubleClick" IsAnimated="True"/>
                <s:YAxisDragModifier/>
            </s:ModifierGroup>
        </s:SciChartSurface.ChartModifier>

    </s:SciChartSurface>

</UserControl>

The UserControl is composed from its parent using a grid:

<Grid>

    <!-- Several other custom controls have been removed for brevity -->

    <GroupBox Grid.Column="7" Header="Scattering History" Style="{StaticResource GbSidesStyle}">
       <Status:ScatteringHistory/>
    </GroupBox>
</Grid>

Finally, the model pieces to which the chart data is bound:

#region Light Scattering data

// TODO: store/retrieve this data in the SensorDataModel used by the current experiment
// (which will eventually allow for real-time analysis)

private IDataSeries<int, double> _LightScatterInstant = new XyDataSeries<int, double>();
public IDataSeries<int, double> LightScatterInstant
{
    get { return _LightScatterInstant; }
    set { Set(ref _LightScatterInstant, value, nameof(LightScatterInstant)); }
}

private IDataSeries<TimeSpan, double> _LightScatterHistory = new XyDataSeries<TimeSpan, double>();
public IDataSeries<TimeSpan, double> LightScatterHistory
{
    get { return _LightScatterHistory; }
    set { Set(ref _LightScatterHistory, value, nameof(LightScatterHistory)); }
}

private void UpdateCameraData(object sender, EventArgs e)
{
    if (Cell.CameraData.KeyPointValues.Count > 0)
    {
        LightScatterInstant.Clear();
        LightScatterInstant.Append(Cell.CameraData.KeyPointIndices, Cell.CameraData.KeyPointValues);

        if (CurrentExperiment != null && (CurrentExperiment.IsStarted && !CurrentExperiment.IsFinished))
        {
            LightScatterHistory.Append(ElapsedTime, Cell.CameraData.KeyPointValues[8]);
        }
    }
}

#endregion
Images
  • You must to post comments
Showing 0 results
Your Answer

Please first to submit.

Try SciChart Today

Start a trial and discover why we are the choice
of demanding developers worldwide

Start TrialCase Studies