High GC pressure on TrackBall mouse move

Hello,

I have noticed a large amount of memory allocations when the Trackball OnMouseMove event tries to compute the pointer position relative to the AdorningCanvas as it can be seen from the stack trace below.

The chart contains a dozen of FastLineSeries with roughly 3000 points each. I think there might be something going on with the Canvas itself that is causing this behavior.  Any help or hint would be very much a


Small Object Heap: code that allocates a lot of memory in SOH

Allocated object type: Byte[]

  Allocated size: 370.9 MB

at ByteStreamGeometryContext.ReadWriteData(bool, byte*, int, int, ref int)

at ByteStreamGeometryContext.GenericPolyTo(IList, bool, bool, bool, int, MIL_SEGMENT_TYPE)

at PolyLineSegment.SerializeData(StreamGeometryContext)

at PathGeometry.GetPathGeometryData()

at Geometry.GetBoundsInternal(Pen, Matrix, double, ToleranceType)

at RenderData.DrawingContextWalk(DrawingContextWalker)

at UIElement.GetContentBounds()

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.CalculateSubgraphBoundsOuterSpace(bool)

at Visual.CalculateSubgraphBoundsInnerSpace(bool)

at Visual.get_VisualDescendantBounds()

at Visual.TrySimpleTransformToAncestor(Visual, bool, ref GeneralTransform, ref Matrix)

at InputElement.TranslatePoint(Point, DependencyObject, DependencyObject, ref bool)

at MouseDevice.GetPosition(IInputElement)

at ChartTrackBallBehavior.OnMouseMove(MouseEventArgs)

at SfChart.OnMouseMove(MouseEventArgs)

at RoutedEventArgs.InvokeHandler(Delegate, Object)

at EventRoute.InvokeHandlersImpl(Object, RoutedEventArgs, bool)

at UIElement.RaiseEventImpl(DependencyObject, RoutedEventArgs)

at UIElement.RaiseTrustedEvent(RoutedEventArgs)

at InputManager.ProcessStagingArea()

at HwndMouseInputProvider.ReportInput(int, InputMode, int, RawMouseActions, int, int, int)

at HwndMouseInputProvider.FilterMessage(int, WindowMessage, int, int, ref bool)

at HwndSource.InputFilterMessage(int, int, int, int, ref bool)

at HwndWrapper.WndProc(int, int, int, int, ref bool)

at ExceptionWrapper.InternalRealCall(Delegate, Object, int)

at ExceptionWrapper.TryCatchWhen(Object, Delegate, Object, int, Delegate)

at Dispatcher.LegacyInvokeImpl(DispatcherPriority, TimeSpan, Delegate, Object, int)

at HwndSubclass.SubclassWndProc(int, int, int, int)

at dynamicClass.IL_STUB_PInvoke(int, int, MonitorEnumProc, int)

at dynamicClass.IL_STUB_PInvoke(int, int, MonitorEnumProc, int)

at Dispatcher.PushFrameImpl(DispatcherFrame)

at Application.RunDispatcher(Object)

at Application.RunInternal(Window)

at App.Main()




8 Replies

NM Nanthini Mahalingam Syncfusion Team January 1, 2024 12:43 PM UTC

Hi Emanuel,


Currently, we are validating the memory allocation with the trackball mouse move event and will provide an update on January 3rd, 2024.


Regards,

Nanthini Mahalingam.



NM Nanthini Mahalingam Syncfusion Team January 3, 2024 01:04 PM UTC

Hi Emanuel,


We have validated the reported issue and attempted to reproduce it on our end. Currently, we were unable to reproduce the memory holding issue on track ball mouse move. We need more information. Have you overridden the member of the MouseMove in the chart track behavior to compute the pointer position? It will help us provide a better solution.


Regards,

Nanthini Mahalingam.



EM Emanuel replied to Nanthini Mahalingam January 3, 2024 01:43 PM UTC

Hello,


Indeed the Trackball behavior is extended, below you can see the implementation:


public class CustomTrackBallBehavior : ChartTrackBallBehavior

{

    public bool IsInputFromMouse { get; private set; } = true;


    private const double Epsilon = 0.001;


    private readonly PropertyInfo? _currentPointInfo;

    private Point _lastPos;


    public CustomTrackBallBehavior()

    {

        _currentPointInfo = GetType().GetProperty("CurrentPoint", BindingFlags.NonPublic | BindingFlags.Instance);

    }


    protected override void OnMouseMove(MouseEventArgs e)

    {

        if (e.LeftButton != MouseButtonState.Pressed)

            return;


        IsInputFromMouse = true;

        base.OnMouseMove(e);


        _lastPos = _currentPointInfo?.GetValue(this) as Point? ?? _lastPos;

    }


    protected override void OnSizeChanged(SizeChangedEventArgs e)

    {

        IsActivated = false;

    }


    protected override void OnMouseLeave(MouseEventArgs e)

    {

        //Suppress default behavior

    }


    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)

    {

        //Suppress default behavior

    }


    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)

    {

        //Suppress default behavior

    }


    public void SetAt(double xValue)

    {

        if (ChartArea.PrimaryAxis is not NumericalAxis axis)

            return;


        var newValue = MathExtensions.Clamp(xValue, (axis.Minimum ?? 0) + Epsilon, (axis.Maximum ?? 3000) - Epsilon);

        Show(_lastPos with { X = ChartArea.ValueToPoint(axis, newValue) });

    }


    public void Move(double dx)

    {

        if(ChartArea.PrimaryAxis is not NumericalAxis axis)

            return;


        var xValue = ChartArea.PointToValue(axis, _lastPos);

        var newValue = MathExtensions.Clamp(xValue + dx, (axis.Minimum ?? 0) + Epsilon, (axis.Maximum ?? 3000) - Epsilon);

        Show(_lastPos with { X = ChartArea.ValueToPoint(axis, newValue) });

    }


    private void Show(Point pos)

    {

        IsInputFromMouse = false;

        IsActivated = true;


        if (AdorningCanvas != null)

            base.OnPointerPositionChanged(pos);


        _lastPos = pos;

    }

}


Basically the trackball is only visible on normal mouse operation if the left mouse button is pressed and the mouse is moving.


Regards,

Emanuel Hristea



NM Nanthini Mahalingam Syncfusion Team January 4, 2024 01:49 PM UTC

Hi Emanuel,


We are validating the code snippet you provided and checking for the memory holding issue. We will update the response within two business days (08/01/2024).


Regards,

Nanthini M.



NM Nanthini Mahalingam Syncfusion Team January 8, 2024 02:18 PM UTC

Hi Emanuel,


Currently, we are checking the memory heap issue on custom trackball behavior with our source. We are working on an alternative way to display the current coordinate point of the trackball and update the status within two business days (10/01/2024). We appreciate your patience.


Regards,

Nanthini M.



NM Nanthini Mahalingam Syncfusion Team January 10, 2024 02:20 PM UTC

Hi Emanuel,


We have validated the memory heap issue at the trackball during the mouse move event on our machine using the performance profiler. We were unable to reproduce the provided call stack, and the memory occupied was less when using the provided code snippet. Therefore, we would like to know more about your exact scenario to reproduce the memory issue. Please let us know your availability so that we can schedule a meeting.


Regards,

Nanthini M.



EM Emanuel replied to Nanthini Mahalingam January 10, 2024 02:34 PM UTC

Hi Nanthini,


Thank you very much for the investigation. Unfortunately I have a very busy schedule, I think a better method would be for me to provide a sample application that reproduces the issue. I will try to come back with something early next week.


Thank you again for your support,

Emanuel Hristea





PR Preethi Rajakandham Syncfusion Team January 11, 2024 01:09 PM UTC

Hi Emanuel,

You're welcome. We will wait until we hear from you.

Regards,

Preethi R


Loader.
Up arrow icon