Charles
Charles

Reputation: 33

Massive memory leak in .NET6.0 dialog

I have been chasing a memory leak and have gotten down to a pretty simple case. Whenever the canvas size changes, the window clears the canvas and adds 1,000 random points to the canvas. It also reports the memory usage in the titlebar of the window. Memory starts out below 2MB. If you grab the corner of the window and move it around a bit, the memory usage skyrockets to over 100MB in 10 sec. and the UI gets sluggish. Stop moving for 10 sec and the memory creeps back to 11MB (Not shown in the titlebar because there isn't an update but never back to the original <2MB).

Is it possible that simple wpf graphics are this broken? Am I doing something wrong? I call GC.Collect() on every repaint, so why does any memory recovery take so long? Release/debug mode doesn't make any difference. Making the lines invisible doesn't make any difference. Changing line characteristics doesn't matter Using different color brushes on each line doesn't matter. The leak is proportional to the number of lines on the canvas.

How can it be that simple lines on a canvas aren't collected when the canvas is cleared?

Any ideas greatly appreciated!

Here's the code:

<Window x:Class="SillyLeakTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" SizeChanged="Window_SizeChanged">
    <Canvas x:Name="theCanvas"/>
</Window>

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace SillyLeakTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Random rand = new Random();
        public MainWindow()
        {
            InitializeComponent();
        }

  
        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            GC.Collect();
            Title = "Memory Used: " + GC.GetTotalMemory(true).ToString("##,#");
          
            Point windowSize = new Point(theCanvas.ActualWidth, theCanvas.ActualHeight);
            Point center = new Point(windowSize.X / 2, windowSize.Y / 2);

            theCanvas.Children.Clear();
            
            SolidColorBrush color = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(1, 255),
                (byte)rand.Next(1, 255), (byte)rand.Next(1, 255)));

            double scale = 1;
            for (int i = 0; i < 1000; i++)
            {
                Point p = new Point(rand.Next(-(int)center.X, (int)center.X), rand.Next(-(int)center.Y, (int)center.Y));
                theCanvas.Children.Add(new Line
                {
                    X1 = center.X + p.Y * scale,
                    Y1 = center.Y - p.X * scale,
                    X2 = center.X + p.Y + 2 * scale,
                    Y2 = center.Y - p.X + 2 * scale,
                    StrokeThickness = 1,
                    //StrokeEndLineCap = PenLineCap.Round,
                    //StrokeStartLineCap = PenLineCap.Round,
                    // Stroke = new SolidColorBrush(P1.TheColor)
                    Stroke = color,
                });
            }
        }
    }
}

Upvotes: 0

Views: 492

Answers (1)

pm100
pm100

Reputation: 50120

OK I can confirm. WPF does some weird sht when debugger attached. Start without debugger via CTRL-F5

There is no screen decoration and the app runs smooth and fast , tops out at ~2.8mb.

Attach debugger from VS and suddenly we have a colored border and that strange debug panel at the top of the screen. Now the memory grows exponentially.

see Different behavior of WPF Application: IDE debugging vs directly running the executable

Upvotes: 1

Related Questions