mono / libgdiplus

C-based implementation of the GDI+ API
http://www.mono-project.com/
MIT License
329 stars 171 forks source link

Memory leak when multi-threading on Linux #708

Open tsvx opened 3 years ago

tsvx commented 3 years ago

This is a duplicate of the bug in the System.Drawing.Common since I do not know exactly what leads to the problem.

Description

Consider this following piece of code:

async Task DrawCollage()
{
    var jpegBytes = File.ReadAllBytes("image.jpg"); // any 2000*1500 px, 24 bpp
    using var collage = new Bitmap(1000, 1000);
    using var g = Graphics.FromImage(collage);
    //using var ms = new MemoryStream(jpegBytes);
    //using var image = Image.FromStream(ms);
    //g.DrawImage(image, 0, 0, 500, 500);
}

Note that every graphics object is disposed properly here.

Frequent serialized calls of this method on different threads lead to enormous memory consumption, even with three last lines commented out. Working Set size increases in proportion to the number of threads involved, but GC Heap does not increase. Uncommenting every line triples the memory consumption.

When I force this method to use one dedicated thread only, no increase in memory consumption is observed.

I expect the memory should not grow as every graphic object is disposed after use.

Configuration

Regression?

The bug is not reproducible on Windows 10 x64 with .NET Core 3.1.

Other information

It seems something keeps being cached after dispose in the thread local storage in the libgdiplus library.

A complete code example to reproduce the problem is here: https://github.com/tsvx/SystemDrawingMemoryLeak It is a work in progress (it reproduces the problem but can be simplified I think).

sharpSteff commented 1 year ago

I have the same issue on

On stackoverflow someone suggested installing libgdiplus 4.2. https://stackoverflow.com/questions/71478697/system-drawing-high-memory-usage-on-linux Unfortunately 20.04 has no 4.2.