dlemstra / Magick.NET

The .NET library for ImageMagick
Apache License 2.0
3.47k stars 415 forks source link

Pixel cache does not seem to be garbage collected #1646

Closed TobiasWolters closed 5 months ago

TobiasWolters commented 5 months ago

Magick.NET version

Magick.NET-Q16-HDRI-AnyCPU, Version 13.6.0

Environment (Operating system, version and so on)

Windows 11 Business, 23H2, 22631.3593

Description

We are using Magick.NET to retrieve information about an image.

In particular, we are doing something along the lines of:

using var imageCollection = new MagickImageCollection();
magickImageCollection.Ping(imageStream);
...

We initialize Magick.NET in the following way:

var configurationFiles = ConfigurationFiles.Default;
configurationFiles.Policy.Data = """
                                         <policymap>
                                             <policy domain="resource" name="memory" value="96MiB"/>
                                             <policy domain="resource" name="map" value="512MiB"/>
                                             <policy domain="resource" name="disk" value="20GiB"/>
                                             <policy domain="system" name="max-memory-request" value="96MiB"/>
                                         </policymap>
                                         """;
MagickNET.Initialize(configurationFiles);

For large images, the entire pixel cache in RAM is used - i.e. all 512 MiB, allowed by the map parameter above.

However, the RAM allocated for the pixel cache never seems to be freed again, although the MagickImageCollection is disposed.

Is it possible to somehow ensure that the allocated RAM for the pixel cache is freed again?

Steps to Reproduce

Use the setup from the description, providing a large image file via the imageStream parameter.

dlemstra commented 5 months ago

There is no pixel cache used when you Ping the image for most of the formats. The memory on the Native side is cleaned up with native code that calls free and returns memory to the operating system. Memory allocated on the .NET side is not immediately returned to the operating system by the garbage collector so I suspect you are seeing that? And are you properly disposing the imageStream?