# Memory leak

**URL:** <https://www.ruby-forum.com/t/memory-leak/240103>\
**Category:** Ruby-Gnome 2\
**Created:** [March 27, 2014, 8:09pm UTC](https://www.ruby-forum.com/t/memory-leak/240103 "2014-03-27T20:09:57Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Detlef\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Detlef\_R](https://www.ruby-forum.com/u/Detlef_R)\
**Post date:** [March 27, 2014, 8:09pm UTC](https://www.ruby-forum.com/t/memory-leak/240103/1 "2014-03-27T20:09:57Z")

</div>

Hi,

I stumbled over a memory leak in ruby gtk or cairo. Here is a short  
example:

require ‘gtk3’

class Win \< Gtk::Window  
def initialize  
super  
set\_default\_size 800, 600  
@it = 0  
self.add\_events Gdk::Event:😷:SCROLL\_MASK  
signal\_connect(:scroll\_event) {|object, event| redraw; false}  
end

```
def redraw
    p @it
    @it += 1

    @backBuffer = Cairo::ImageSurface.new Cairo::Format::RGB24, 800, 

```

600  
cc = Cairo::Context.new @backBuffer  
cc.antialias = :none  
cc.set\_source\_rgb 1.0, 1.0, 1.0  
cc.paint

```
    cb = self.window.create_cairo_context
    cb.set_source @backBuffer
    cb.paint
    true
end

```

end

win = Win.new  
win.show\_all  
Gtk.main

if you scroll in the window that opens, on scrolls with the mouse wheel,  
after ~ 2000 ticks the memory usage on my system is around 3.6 GB. It  
seems, that the image memory is not released. If I comment out the line  
where the back buffer is created

```
    @backBuffer = Cairo::ImageSurface.new Cairo::Format::RGB24, 800, 

```

600

the problem is gone. I don’t know where to look for the solution.

Cheers, detlef

---

<div class="post-metadata">

**Author:** ![Detlef\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Detlef\_R](https://www.ruby-forum.com/u/Detlef_R)\
**Post date:** [March 27, 2014, 8:48pm UTC](https://www.ruby-forum.com/t/memory-leak/240103/2 "2014-03-27T20:48:13Z")

</div>

Am 27.03.2014 20:08, schrieb Detlef R.:

> If I comment out the line  
> where the back buffer is created
> 
> ```
> @backBuffer = Cairo::ImageSurface.new Cairo::Format::RGB24, 800, 600
> 
> ```
> 
> the problem is gone. I don’t know where to look for the solution.

I was not precisely in my last mail. I didn’t commented out the back  
buffer creation, but moved it to the configure\_event handler. That fixed  
the problem almost for me, but the bug stays.

Cheers, detlef

---

<div class="post-metadata">

**Author:** ![Detlef\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Detlef\_R](https://www.ruby-forum.com/u/Detlef_R)\
**Post date:** [March 28, 2014, 1:25am UTC](https://www.ruby-forum.com/t/memory-leak/240103/3 "2014-03-28T01:25:34Z")

</div>

On Thu, 2014-03-27 at 20:08 +0100, Detlef R. wrote:

> Hi,
> 
> I stumbled over a memory leak in ruby gtk or cairo.

Unfortunately I can confirm that problem.  
So I really hope Kouhei S. or other experts can comment on it – and  
maybe on your previous question too (missing gdk\_pixbuf\_get\_from\_window)  
for which I have no idea.

For your current problem: Of course generally we would not create a new  
surface for each redraw, but create one in initialize method I think.  
The cairo problem is depending on cc.paint, if I uncomment it in the  
source below I have memory leak. But if I also uncomment #cc.destroy  
and #backBuffer.destroy below I have no leak. I always wondered about  
that destroy methods… I do not really know something about cairo’s  
memory handling and rcairo bindings – maybe cairo painting operations  
like cc.paint do increase reference count to the surface?

require ‘gtk3’

class Win \< Gtk::Window  
def initialize  
super  
set\_default\_size 800, 600  
@it = 0  
self.add\_events Gdk::Event:😷:SCROLL\_MASK  
signal\_connect(:scroll\_event) {|object, event| redraw; false}  
end

```
def redraw
    p @it
    @it += 1
    backBuffer = Cairo::ImageSurface.new Cairo::Format::RGB24, 800, 

```

600  
cc = Cairo::Context.new backBuffer  
#cc.paint  
#cc.destroy  
#backBuffer.destroy  
#GC.start  
true  
end  
end

win = Win.new  
win.show\_all  
Gtk.main

---

<div class="post-metadata">

**Author:** ![Detlef\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Detlef\_R](https://www.ruby-forum.com/u/Detlef_R)\
**Post date:** [April 4, 2014, 7:37pm UTC](https://www.ruby-forum.com/t/memory-leak/240103/4 "2014-04-04T19:37:14Z")

</div>

Hi Kou,

I’ve installed rcairo von git with your fix included. For my test  
program it fixed the problem, if I start the GC on regular intervals. Is  
there a better solution then start the GC on my own every x draw calls?  
It’s only a theoretical question, cause I fixed my program on the right  
way, as I already wrote.

Thanks allot! Cheers, detlef

Am 31.03.2014 15:37, schrieb Kouhei S.:

---

<div class="post-metadata">

**Author:** ![Detlef\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Detlef\_R](https://www.ruby-forum.com/u/Detlef_R)\
**Post date:** [March 31, 2014, 3:38pm UTC](https://www.ruby-forum.com/t/memory-leak/240103/5 "2014-03-31T15:38:24Z")

</div>

Hi,

In [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
“[ruby-gnome2-devel-en] memory leak” on Thu, 27 Mar 2014 20:08:01  
+0100,  
Detlef R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I stumbled over a memory leak in ruby gtk or cairo. Here is a short example:

Thanks for your report!  
I’ve fixed it in rcairo at master.

–  
kou

---

<div class="post-metadata">

**Author:** ![Detlef\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Detlef\_R](https://www.ruby-forum.com/u/Detlef_R)\
**Post date:** [April 4, 2014, 10:31pm UTC](https://www.ruby-forum.com/t/memory-leak/240103/6 "2014-04-04T22:31:52Z")

</div>

On Fri, 2014-04-04 at 19:29 +0200, Detlef R. wrote:

> Hi Kou,
> 
> I’ve installed rcairo von git with your fix included. For my test  
> program it fixed the problem, if I start the GC on regular intervals.  
> Is  
> there a better solution then start the GC on my own every x draw  
> calls?  
> It’s only a theoretical question, cause I fixed my program on the  
> right  
> way, as I already wrote.

I tried to find an explanation for that behaviour, and found this nice  
page:

[http://samsaffron.com/archive/2013/11/22/demystifying-the-ruby-gc](http://samsaffron.com/archive/2013/11/22/demystifying-the-ruby-gc)

Seems that garbage collection is triggered by size of allocated memory  
– maybe size of memory allocated by cairo is not visible to GC?

I am using Ruby 2.0 (MRI) and have the same issues as Detlef R..  
Manually invoking GC when unused cairo objects exists seems to prevent  
excessive heap usage, but may slow down performance.

Question: Should we manually call cairo’s destroy methods when we are  
done with cairo objects as in

def redraw  
backBuffer = Cairo::ImageSurface.new Cairo::Format::RGB24, 800, 600  
cc = Cairo::Context.new backBuffer  
cc.paint  
#cc.destroy  
#backBuffer.destroy  
#GC.start  
true  
end

Unfortunately rcairo’s destroy methods are undocumented, so I was  
wondering about it from the beginning.

Best regards,

Stefan S.

---

<div class="post-metadata">

**Author:** ![Detlef\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Detlef\_R](https://www.ruby-forum.com/u/Detlef_R)\
**Post date:** [April 6, 2014, 2:25am UTC](https://www.ruby-forum.com/t/memory-leak/240103/7 "2014-04-06T02:25:15Z")

</div>

On Sat, 2014-04-05 at 08:52 +0900, Kouhei S. wrote:

> Here is the recommended way! It is Ruby-ish code. 🙂
> 
> Cairo::ImageSurface.new Cairo::Format::RGB24, 800, 600 do |backBuffer|  
> Cairo::Context.new backBuffer do |cc|  
> cc.paint  
> end  
> end

Nice idea – using block parameters as we do for file operation when  
file is automatically closed when block terminates. Works fine, thanks.

---

<div class="post-metadata">

**Author:** ![Detlef\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Detlef\_R](https://www.ruby-forum.com/u/Detlef_R)\
**Post date:** [April 5, 2014, 1:53am UTC](https://www.ruby-forum.com/t/memory-leak/240103/8 "2014-04-05T01:53:26Z")

</div>

Hi,

In [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
“Re: [ruby-gnome2-devel-en] memory leak” on Fri, 04 Apr 2014 22:25:00  
+0200,  
Stefan S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> true  
> end
> 
> Unfortunately rcairo’s destroy methods are undocumented, so I was  
> wondering about it from the beginning.

Here is the recommended way! It is Ruby-ish code. 🙂

Cairo::ImageSurface.new Cairo::Format::RGB24, 800, 600 do |backBuffer|  
Cairo::Context.new backBuffer do |cc|  
cc.paint  
end  
end

## Thanks,

kou
