Skip to content

Known issue: WPF Image memory leak when remove image from visual tree #2397

Open
@lindexi

Description

@lindexi
  • .NET Core Version: 3.1.100
  • Windows version: 18363
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
  • Is this bug related specifically to tooling in Visual Studio No

Problem description:

The image source will memory leak when we remove the image from visual tree before we set the image source as null

Step:

  1. Set the image source
  2. Add image in the VisualTree and wait the image show
  3. Remove image from the visual tree and then set the image source as null

And you can find the image source object never free

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // Remove the current Image control from the  visual tree and set source is null when click button.
            // Then new a image control and add source to the RenderTargetBitmap object and show it.
            // You can see the gc never delete the RenderTargetBitmap object that make  memory leak.

            var oldBorder = RootGrid.Children.OfType<Border>().LastOrDefault();
            if (oldBorder != null)
            {
                var oldImage = (Image)oldBorder.Child;

                // In order to solve it , you should set the image.Source is null and use UpdateLayout.
                // The below code can solve it.
                // oldImage.Source = null;
                // oldImage.UpdateLayout();

                // Remove the current Image control from the  visual tree.
                RootGrid.Children.Remove(oldBorder);
                oldImage.Source = null;
                Borders.Add(oldBorder);
            }

            var bitmap = new RenderTargetBitmap(1024, 1024, 96, 96, PixelFormats.Default);

            var image = new Image { Source = bitmap };
            var border = new Border { Child = image };
            RootGrid.Children.Add(border);

            // In order to facilitate changes in memory, after each operation will be garbage collection
            GC.Collect();
        }

        public readonly List<Border> Borders = new List<Border>();

Actual behavior:

The Image memory leak

Expected behavior:

The image source object can be free

Minimal repro:

https://github.com/dotnet-campus/wpf-issues/tree/master/ImageMemoryLeakDotNetCore

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Status

Todo

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions