mono / gtk-sharp

Gtk# is a Mono/.NET binding to the cross platform Gtk+ GUI toolkit and the foundation of most GUI apps built with Mono
http://www.mono-project.com/GtkSharp
Other
426 stars 141 forks source link

pango-sharp leaks memory #233

Open Rombersoft opened 6 years ago

Rombersoft commented 6 years ago

When I use this code

  using (Pango.Layout layout = Pango.CairoHelper.CreateLayout(cr))
            {
                layout.Width = Pango.Units.FromPixels(500);
                layout.Height = Pango.Units.FromPixels(500);
                layout.Wrap = Pango.WrapMode.Word;
                layout.Alignment = Pango.Alignment.Left;
                layout.Ellipsize = Pango.EllipsizeMode.Start;
                layout.FontDescription = Pango.FontDescription.FromString("Ahafoni CLM Bold 20");
                layout.SetMarkup("<span color=\"#ff00ff\">It’s like setting up text in word or writer <span style=\"italic\">You can have indents, </span> sizes, fonts, etc etc. In this example Pango.Layout, the width is set by converting the window width into pango units because layouts are not measured in pixels. The wrap goes hand in hand with width so that any long text will wrap at the set width value. The FontDescription is quite handy. Here you can define your font. Thanks go to TD on the #mono channel for his tips here. If you want to know the names of available fonts you can enter here, go to gedit and look at the available font names. In the example above, I have the font name of “Ahafoni CLM”, the weight of “Bold” and size of 100.</span>");
                Pango.CairoHelper.ShowLayout(cr, layout);
            }

My memory leaks every 2 seconds += 2Mb.

When I comment this code memory alocate is permanent

version pango are 2.99 & 2.12

Demonstrative video and example you can find here https://github.com/Rombersoft/pango-sharp-bug

Therzok commented 6 years ago

I'll take a look at the sample and figure it out.

On the note of what's going on, I see no obvious retention of memory through classic event handler leaking.

Is this the latest version of gtk-sharp-2-12-branch?

Few things to note:

I looked over the methods you're using and their refcounting semantics in gtk#, and they don't seem wrong.

Rombersoft commented 6 years ago

Thank you as for "StopAnimation doesn't work, since _idTimer isnt' set." I'll fix it

This bug happens on all GTK# versions

As for waiting for finalization I can wait BUT HOW MANY minutes I must wait? Say me quantity of waiting minutes and I will do experience.

Also I would want to pay your attention to this line:

https://github.com/Rombersoft/pango-sharp-bug/blob/7135ee9a24bd94026ff59dba78c936abb8c95139/Simple_GTK/GraphicsController.cs#L140

Every time when I redraw this ImageSurface I must create new instance at the begin of method and dispose it at the end of method otherwise if I use one instance again and again my memory also leaks very fast. I think that is not right to create new ImageSurface for every animation step because it is bad performance. Maybe it exists some way to clear this surface without creating new instance

Therzok commented 6 years ago

I'm seeing this when running locally:

Set MONO_CAIRO_DEBUG_DISPOSE to track allocation traces
Cairo.Surface is leaking, programmer is missing a call to Dispose
Set MONO_CAIRO_DEBUG_DISPOSE to track allocation traces
Cairo.Surface is leaking, programmer is missing a call to Dispose

The native memory is not reclaimed in the finalizer for surface. I haven't touched Cairo itself for how it manages native memory, so this is a cairo bug, not a pango bug.

The code you linked here: https://github.com/Rombersoft/pango-sharp-bug/blob/7135ee9a24bd94026ff59dba78c936abb8c95139/Simple_GTK/GraphicsController.cs#L140

The thing with _surface is that you have no guaranteed order of events here. OnDrawn does not necessarily run right after QueueDraw is called.

So, what happens is:

So, that means, you should dispose of all the ImageSurfaces you create.

        public void FillCommonToBuffer()
        {
            if (_surface != null)
                _surface.Dispose(); // Check this! leaks fixed.
            _surface = new ImageSurface(Format.ARGB32, _width, _height);

That made memory stable for me. I also got rid of all the GetTarget().Dispose() calls everywhere.

Rombersoft commented 6 years ago

This will not resolve problem with pango.