Ruby Forum Ruby-Gnome 2 > pixbuf - memory leak?

Posted by Vladimir Konrad (prhlava)
on 17.05.2008 15:31
Hello,

I am using gtk2 for image processing and the memory usage consistently
grows (memory never gets reclaimed).

The code is along the lines:

# pixell coordinates to memory address of the first byte)
def p2i(px, py, channels, rowstride)
  px * channels + py * rowstride
end

def process_image(pixbuf, output_dir)
  pixbuf.width.times do |x|
    pixbuf.height.times do |y|
      sample = pixbuf.pixels[p2i(x, y, pixbuf.n_channels,
pixbuf.rowstride), pixbuf.n_channels]
      # do something with the sample here
    end
  end
end

def process_images(input_dir, output_dir)
    image_paths = Dir.glob(input_dir + "/*.png").sort

    for ip in image_paths
        pixbuf = Gdk::Pixbuf.new(ip)
  process_image(pixbuf, output_dir)
    end

end

Am i supposed to call garbage collection by hand or the gtk2 is not
supposed to be used like this?

Vlad
Posted by Detlef Reichl (Guest)
on 17.05.2008 16:43
(Received via mailing list)
Am Samstag, den 17.05.2008, 15:31 +0200 schrieb Vladimir Konrad:
> Hello,
> 
> I am using gtk2 for image processing and the memory usage consistently
> grows (memory never gets reclaimed).

[snip]
> 
> Am i supposed to call garbage collection by hand

yes, for now you have to start the GC on your own if you big amounts of
data very fast.

Cheers, detlef
Posted by Vladimir Konrad (prhlava)
on 17.05.2008 18:33
>> Hello,
>> 
>> I am using gtk2 for image processing and the memory usage consistently
>> grows (memory never gets reclaimed).
> 
> [snip]
>> 
>> Am i supposed to call garbage collection by hand
> 
> yes, for now you have to start the GC on your own if you big amounts of
> data very fast.

Thanks for the pointer.

Well, to process one image takes minutes...

I have put the GC.start at the relevant place (in the cycle after 
process_imate() call) and will see what happens...

Vlad
Posted by Detlef Reichl (Guest)
on 17.05.2008 19:15
(Received via mailing list)
Am Samstag, den 17.05.2008, 18:33 +0200 schrieb Vladimir Konrad:
> > data very fast.
> 
> Thanks for the pointer.
> 
> Well, to process one image takes minutes...
> 
Sorry, i've overlooked something in your example. Here

sample = pixbuf.pixels[p2i(x, y, pixbuf.n_channels,
pixbuf.rowstride), pixbuf.n_channels]

you create for every single pixle an array with all pixels from the
pixbuf. That must be horrible slow. Change your method as followed:

def process_image(pixbuf, output_dir)
  pixels = pixbuf.pixels
  pixbuf.width.times do |x|
    pixbuf.height.times do |y|
      sample = pixels[p2i(x, y, pixbuf.n_channels,
pixbuf.rowstride), pixbuf.n_channels]
      # do something with the sample here
    end
  end
end


Cheers, detlef
Posted by Detlef Reichl (Guest)
on 17.05.2008 19:25
(Received via mailing list)
Am Samstag, den 17.05.2008, 19:14 +0200 schrieb Detlef Reichl:

Another speedup you'll get, if you precalculate some variables like
this:

  pixels = pixbuf.pixels
  w = pixbuf.width
  h = pixbuf.height

  h.times do |y|
    rs = y * pixbuf.rowstride
    ch = pixbuf.n_channels
    w.times do |x|
      sample = pixels[x * ch + rs]
    end
  end



Cheers, detlef
Posted by Vladimir Konrad (prhlava)
on 18.05.2008 18:36
Detlef Reichl wrote:

> you create for every single pixle an array with all pixels from the
> pixbuf. That must be horrible slow. Change your method as followed:

(blushing for being stupid publicly ;-)

Thanks to all who replied,

I have re-done the method (create pixels array once per picture) - it 
works faster and also it looks that the memory usage is OK.

Vlad