C library binding memory leak problem LONG

Hello all - I just finished an initial release of a Ruby binding to libmagic
yesterday, and it seemed to work well. Well, today I was playing around with
it, and I decided to see how well my garbage collection routine was working.
I hacked together the following small test, and watched the process run by
doing watch -n 1 ‘ps aux | grep test.rb’

file test.rb

···

#!/usr/bin/ruby

require “filemagic”

def do_file(filename)
fm = FileMagic.new(0)
puts fm.file(filename)
end

loop do
do_file(“test.rb”)
sleep 1
end

The test program leaked memory like a sieve. I decided to add a
printf(“Free!\n”) to my garbage collection routine to see when it was freeing.

/* Garbage collection routine */
static void free_cookie(magic_t cookie)
{
printf(“Free!\n”);
if (cookie) magic_close(cookie);
}

For some reason, none of the objects are freed until I interrupt with ctrl-c.

travis@travis tmp $ ruby test.rb
a /usr/bin/ruby script text executable
a /usr/bin/ruby script text executable
a /usr/bin/ruby script text executable
a /usr/bin/ruby script text executable
a /usr/bin/ruby script text executable
a /usr/bin/ruby script text executable
test.rb:12:in sleep': Interrupt from test.rb:12 from test.rb:11:inloop’
from test.rb:11
Free!
Free!
Free!
Free!
Free!
Free!

I decided to add a manual close method, and it stopped the leaking.

static VALUE magick_close(VALUE class)
{
magic_t cookie;
GetMagicCookie(class, cookie);
magic_close(cookie);
return Qnil;
}

file test.rb

#!/usr/bin/ruby

require “filemagic”

def do_file(filename)
fm = FileMagic.new(0)
puts fm.file(filename)
fm.close
end

loop do
do_file(“test.rb”)
sleep 1
end

Can anyone tell me why my objects aren’t being garbage collected until the
end of the program? If you want the source for the entire lib(~130 lines),
you can get it at http://grub.ath.cx/filemagic/ruby-filemagic-0.1.0.tar.gz

Thanks in advance,
Travis Whitton whitton@atlantic.net

Hi,

···

At Wed, 30 Jul 2003 11:36:20 +0900, Travis Whitton wrote:

Can anyone tell me why my objects aren’t being garbage collected until the
end of the program?

It is very difficult to predict when GC runs, and whether a
particular object will be collected.

In general, #close method or similar which release its
resources is necessary for such purpose. Also block style
method would be better.


Nobu Nakada