PintaProject / Pinta

Simple GTK# Paint Program
http://www.pinta-project.com/
MIT License
1.86k stars 277 forks source link

Memory usage skyrockets when doing anything in Pinta #939

Closed khoidauminh closed 1 week ago

khoidauminh commented 3 months ago

To Reproduce

  1. In Pinta, select a brush/pencil tool and start drawing;
  2. Keep drawing and watch as its memory usage goes up.

It's also possible to cause the memory usage to go up by just zooming in and out of the canvas, selecting random places in the canvas, etc. But drawing usually drives the RAM usage up the most.

Additional Info

https://github.com/user-attachments/assets/192012e4-259d-4437-a5a4-b4b2ae7c14f5

Commit that introduced this regression: #685

badcel commented 3 months ago

Can Confirm on Fedora 40.

cameronwhite commented 3 months ago

Confirmed on macOS as well. If I launch Pinta with the --debug flag, which forces the GC to run very frequently (https://github.com/PintaProject/Pinta/blob/master/Pinta/Main.cs#L107) then I didn't observe any major memory growth, so that might be a good starting point for investigation

potatoes1286 commented 3 months ago

Debug flag does seem to fix it from me (I had been seeing >10GB ram usage just adding text!), however even with debug on it still experiences heavy >3GB ram spikes with accompanying lag spikes when zooming in extremely low. image

cameronwhite commented 3 months ago

That might be a somewhat separate issue - the canvas renderer isn't as efficient when zooming in after the port to GTK4 since we can't do partial redraws of only the visible area. But it could also be related somewhat to the GC issue if the Cairo.ImageSurface used by the canvas isn't being collected quickly enough, since the Cairo.ImageSurface binding doesn't currently inform the GC about the native memory size it represents.

cameronwhite commented 3 months ago

Just recording notes from my investigation: Adding an explicit context.Dispose () at the end of PintaCanvas.Draw() https://github.com/PintaProject/Pinta/blob/ebf0335bd1da1721cacdbfd69572115c7a9240e5/Pinta.Gui.Widgets/Widgets/Canvas/PintaCanvas.cs#L148 fixes the vast majority of the memory usage increase

This particular Cairo.Context likely has a big effect on memory usage since it can be the last reference to a temporary Cairo surface from the GTK widget (https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gsk/gskrendernodeimpl.c#L3495)

We can make this fix in Pinta once there's a new gir.core release with the fixes for https://github.com/gircore/gir.core/issues/1109

khoidauminh commented 1 week ago

Thank you!