On Feb 19, 2008 8:59 AM, evanwebb / gmail.com <evanwebb / gmail.com> wrote:
> Not a bug in any way. It's simply that the garbage collector has not
> been trigger. It runs only when it needs to. As you realized you, you
> can force it to run by doing 'GC.start'. If you run 'GC.start' at the
> end of your program, you'll see the memory reclaimed.
>
> This is a typical behavior for a mark/sweep garbage collector. Perl
> and Python are reference count, freeing memory the instant it goes out
> of scope. Ruby waits to free memory until it needs memory to free some.
>
>

Basically it's true. But notice that this program should use constant
of maxium memory (maybe I'm wrong). When method 'leaker' is finished
all objects created in it are candidates to free (but GC isn't called
yet) because there is no reference to them (in particular binding or
scope reference). When method 'leaker' is called again, Ruby tries
create new objects and instead of increasing heap capacity it should
run GC first and frees all unnecessary objects.

Calling manually GC is not solution because... it isn't work in this
case. Calling GC.start after 'leaker' frees some memory but heap
capacity is constanly increased so it leads to using big amount of
memory. Joel VanderWerf showed it in his graph.

Second, GC.start shouldn't be used in typical case. It could affect
whole program (specially slow down program ;)).

<code>
def leaker
  a = Array.new(1_000_000) {|i| "blah"}
end

loop do
  printf "%10s", `ps h -o rss #{$$}`
  leaker
end
</code>

Why this program doesn't cause memory leaks?

btw, great story about GC from why the lucky stiff:
http://whytheluckystiff.net/articles/theFullyUpturnedBin.html
-- 
Radosw Bu„Šat

http://radarek.jogger.pl - m blog