Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apparent memory leak with image resize #707

Closed
3 tasks done
shadowndacorner opened this issue Jul 28, 2020 · 7 comments
Closed
3 tasks done

Apparent memory leak with image resize #707

shadowndacorner opened this issue Jul 28, 2020 · 7 comments

Comments

@shadowndacorner
Copy link

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am using the latest version of Magick.NET
  • I have searched open and closed issues to ensure it has not already been reported

Description

My issue seems similar to this comment in #340, but it doesn't seem to have ever been addressed. It appears that MagickImage.Resize has a memory leak. I have come to this conclusion experimentally rather than via debugging the library manually, but the snipped code below does not leak memory if I comment out the image.Resize(...) line, whereas it does leak memory otherwise. I have observed this in Docker (based on the image mcr.microsoft.com/dotnet/core/sdk:2.2).

Steps to Reproduce

The container's memory balloons if I continuously make requests to the endpoint containing this code. I imagine simply calling this code in a while loop would exhibit the same behavior (I can provide the full controller if necessary, but figured I would limit it for brevity).

// ImageController.cs
var format = ...; // computed from URL

// imageData is a byte array
Debug.Log($"Creating image object...");
using (var image = new MagickImage(imageData, format))
{
    if (image.Width <= 512 && image.Height <= 512)
    {
        var str = new MemoryStream(imageData);
        Debug.Log($"Smaller than 512, returning...");
        return File(str, http.ResponseHeaders["Content-Type"]);
    }

    int targetWidth = Math.Min(image.Width, 512);
    int targetHeight = Math.Min(image.Height, 512);

    var size = new MagickGeometry(targetWidth, targetHeight);
    Debug.Log($"Resizing...");

    // Commenting out this line prevents the code from leaking memory
    image.Resize(size);

    // Save the result
    var data = image.ToByteArray();
    Debug.Log($"Resized, returning...");
    {
        var str = new MemoryStream(data);
        return File(str, http.ResponseHeaders["Content-Type"]);
    }
}

System Configuration

  • Magick.NET version: Magick.NET-Q8-AnyCPU 7.21.1.0
  • Environment (Operating system, version and so on): Docker Desktop for Windows 10, Docker on Amazon Linux 15. Container based on mcr.microsoft.com/dotnet/core/sdk:2.2
  • Additional information:
@dlemstra
Copy link
Owner

What happens when you do using var str = new MemoryStream(data); instead?

@dlemstra
Copy link
Owner

Would it be possible to create a super tiny sample project that includes a Dockerfile and demonstrates the issue and publish that on github @shadowndacorner.

@shadowndacorner
Copy link
Author

Sorry for the very delayed response, we ended up taking a different approach due to deadlines on the project, so this has been somewhat on the backburner for me.

After fighting with it for awhile, I couldn't tell for sure if the issue was actually a memory leak in this library or if it was an issue with the .NET garbage collector not handling large allocations well causing memory usage to balloon over time (stuff like this makes me loathe garbage collection...). Regardless, I will set up a minimal git repository that can reproduce the issue soon.

Thanks, and I apologize again for the late response!

@dlemstra
Copy link
Owner

dlemstra commented Jan 1, 2021

Ping @shadowndacorner ?

@jkavanaghrdm
Copy link

@shadowndacorner Can you share any details on the different approach you took?

@kaktuspalme
Copy link

Maybe someone will stumble across the same problem as me. I'm using Magick.NET in a ASP.NET Core application inside a linux docker container. An image conversion is triggered by a rabbitmq message. What happened was that the application was using much more memory than it should. After analysing memory and searching for leaks etc. I finally stumbled across this:
dotnet/runtime#13301 (comment)

Setting the environment to either MALLOC_TRIM_THRESHOLD_=100000 or GLIBC_TUNABLES=glibc.malloc.trim_threshold=100000 as mentioned in the comment above resolved my issue.

@Waterball12
Copy link

@kaktuspalme Thanks for sharing that, I was having memory issues using Magick.NET in a ASP.NET Web API inside a docker container. My application was growing slowly until it reaches 1GB and crashes and I couldn't understand why it was happening because I was disposing everything that was disposable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants