Memory leak in DrawingContext.DrawGeometry
See original GitHub issueHello, there seems to be some sort of leak when repeatedly using the DrawingContext.DrawGeometry method to fill geometries with different shapes.
To reproduce, add the following Control to an empty Window:
public class TestControl : Control
{
Point mousePosition = new Point();
Random rnd = new Random();
int segmentCount = 20;
double radius = 100;
protected override void OnPointerMoved(PointerEventArgs e)
{
mousePosition = e.GetPosition(this);
this.InvalidateVisual();
}
public override void Render(DrawingContext context)
{
//So that we capture the PointerMoved events
context.FillRectangle(Brushes.White, new Rect(0, 0, this.Bounds.Width, this.Bounds.Height));
PathFigure fig = new PathFigure() { StartPoint = new Point(mousePosition.X + radius, mousePosition.Y) };
for (int i = 0; i < segmentCount; i++)
{
//Geometry always has the same shape: no leak
//fig.Segments.Add(new LineSegment() { Point = new Point(mousePosition.X + radius * Math.Cos(i * 2 * Math.PI / segmentCount), mousePosition.Y + radius * Math.Sin(i * 2 * Math.PI / segmentCount)) });
//Geometry shape changes at every redraw: leak!
fig.Segments.Add(new LineSegment() { Point = new Point(mousePosition.X + radius * Math.Cos(i * 2 * Math.PI / segmentCount) * rnd.NextDouble(), mousePosition.Y + radius * Math.Sin(i * 2 * Math.PI / segmentCount) * rnd.NextDouble()) });
}
fig.IsClosed = true;
PathGeometry testGeometry = new PathGeometry();
testGeometry.Figures.Add(fig);
//Stroke: no leak
//context.DrawGeometry(null, new Pen(Brushes.Blue), testGeometry);
//Fill: leak!
context.DrawGeometry(Brushes.Blue, null, testGeometry);
}
}
Then run the program and quickly move the mouse around in the window. Each time the mouse moves, the control is repainted with a geometry with a different (random) shape; at the same time, the memory usage will go up steadily.
I had a look with the profiler, and it seems to be mostly unmanaged memory:
That Dictionary<IntPtr, WeakReference> SkiaSharp.HandleDictionary.instances
looks suspicious…
I first noticed this while using AvaloniaEdit: the SelectionLayer there draws the text selection using DrawGeometry, and this causes the control to use increasing amounts of memory as the user selects text regions with different shapes.
The issue:
- Happens with Avalonia 0.10.0-preview1 - 0.10.0-preview3, but not with 0.9.12
- Happens on both Windows 10 and Ubuntu 20.04
- Does not happen if the geometry has the same shape, even though the points making it up are still computed at every redraw: if you replace the relevant line with the commented line in the code above, the control draws a 20-sided polygon centered at the mouse pointer rather than a random shape; in this case, the leak does not occur.
- Does not happen if the geometry is stroked rather than filled (see comments in code).
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (7 by maintainers)
BTW, thanks for the fantasic repro @arklumpus !
I think there is still some leak, my code, everything is cached:
https://github.com/wieslawsoltes/Core2D/blob/404ad16d8d8b205ec7858b6f3355020c31c0be65/src/Core2D.UI/Renderer/Nodes/PathDrawNode.cs#L32
Got 57.5MB to 1.6GB memory usage jump in seconds.