.NET6.0 对话框中的大量内存泄漏

Massive memory leak in .NET6.0 dialog

我一直在追查内存泄漏问题,现在已经归结为一个非常简单的案例。每当 canvas 大小发生变化时,window 会清除 canvas 并向 canvas 添加 1,000 个随机点。它还会在 window 的标题栏中报告内存使用情况。 内存开始低于 2MB。 如果您抓住 window 的一角并将其移动一点,内存使用量会在 10 秒内飙升至超过 100MB。 UI 变得迟钝。停止移动 10 秒,内存逐渐回到 11MB(标题栏中没有显示,因为没有更新,但永远不会回到原来的 <2MB)。

难不成简单的wpf图形就这么烂了?难道我做错了什么?我在每次重绘时调用 GC.Collect(),那么为什么任何内存恢复都需要这么长时间? Release/debug 模式没有任何区别。使线条不可见没有任何区别。改变线条特征并不重要在每条线上使用不同颜色的画笔并不重要。泄漏与 canvas.

上的行数成正比

当 canvas 被清除时,canvas 上的简单行怎么可能不被收集?

非常感谢任何想法!

代码如下:

<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,
                });
            }
        }
    }
}

好的,我可以确认。 WPF 在附加调试器时会执行一些奇怪的操作。通过 CTRL-F5

在没有调试器的情况下启动

没有屏幕装饰,应用程序运行流畅快速,最高可达 ~2.8mb。

从 VS 附加调试器,突然我们在屏幕顶部出现了一个彩色边框和那个奇怪的调试面板。现在内存呈指数级增长。