Re: Help! define_method leaking procs...
- From: Eric Mahurin <eric_mahurin@xxxxxxxxx>
- Date: Sun, 16 Oct 2005 22:40:40 +0900
--- Yohanes Santoso <ysantoso-rubytalk@xxxxxxxxxxxxxxxxxxxxx>
wrote:
> Eric Mahurin <eric_mahurin@xxxxxxxxx> writes:
>
> >> That is still not a valid way to detect leak as that still
> >> depends on
> >> VmSize value. Ruby could be freeing every allocation and
> the
> >> Vmsize
> >> would still grow.
> >
> > But it is not.
>
> Be careful, 1. there is no evidence yet that ruby is not
> freeing every
> allocation, and 2. I am not saying there is no memory leak
> caused by
> define_method.
>
> What I have been saying is, you can't use VmSize as an
> indicator of
> memory leak. I have shown examples where the order of free()
> can
> affect VmSize.
>
> Here is an alternative scenario that would have resulted in
> what you
> are seeing: ruby could have free()-ed all its allocations
> properly
> when you call GC.start, but may free() them in different
> order on each
> test case which result in you seeing different VmSize values.
>
> Probably that is not what happens; Probably there really is a
> genuine
> memory leak; But you can't determine which scenario is
> happening from
> VmSize value.
>
> > Have you tried this example? On my 768MB machine, top
> shows it
> > filling my physical memory and then the the CPU drops to
> about 3%
> > because it starts swapping and my machine becomes very
> unresponsive.
> > I'd say that's a good indication that top is reporting the
> right
> > thing.
>
> This only shows whether the free-ing is done immediately or
> not. Thus,
> why my example program focuses in the immediateness of
> freeing.
>
> > You could consider this case a bug in ruby or a bug in the
> > simple test case above. It doesn't matter where the fault
> > lies, it still shows a memory leak.
>
> Memory leak is tricky to show since it requires one to prove
> that
> there is an allocation that is not free-ed by the time the
> process
> ends.
Just because a process frees all its memory before it
terminates doesn't mean there isn't a leak. That doesn't help
too much if you run out of memory before the process is done.
I've seen 2 definitions: a) when a program isn't freeing memory
that isn't used anymore, b) when a program loses all references
to memory that isn't being freed. From the ruby script level
for this example, by both of these definitions it is a memory
leak. From ruby itself, ruby probably still has references to
the memory, so (b) may not call it a "memory leak". To me (a)
is the right definition because it describes symtoms not the
mechanism. If any program keeps growing in memory and it
shouldn't, I'd say it has a memory leak. It doesn't matter how
it comes about and whether or not the program could free the
memory if it was fixed, it is still "leaking" memory.
> However, there are evidences (search the archive for GC
> problems) that
> the GC is too conservative (read: lazy) and stupid in some
> cases. Sometimes, you need to drop the clue book on its head,
> like
> doing a=nil. Without the a=nil, the number of objects is not
> decreased
> by much after GC.
>
> > The point is you better be careful with closures
> (block/lambda)
>
> Yes, be careful as the GC is a lazy bum.
If you want to assign blame to ruby, the problem is not GC.
The problem is that closures hold strong references to all
variables in the scope whether or not they are used. One of my
solutions was to make references (in Proc#binding) to currently
unused variables (by the closure) "weak", so that they wouldn't
prevent GC.
> In any case, here is another 'fixed' version.
>
> ysantoso@jenny:/tmp$ ruby -e 'n=2**13;for i in (1..n) do
> a=(1..i).to_a;self.class.send(:define_method,:"f#{i}"){i*i}
> end;GC.start;
>
IO.readlines("/proc/#{Process.pid}/status").grep(/VmSize/).display'
>
> VmSize: 11268 kB
This is because the "for" loop (which uses #each) doesn't
create the same type of block/lambda that the normal block
(after a method call) does. In the above example, "a" is in
the outer scope. With using #each and a block directly, "a" is
a local to each interation that it is yielded - it is a
different variable on each iteration. The "for" loop you
showed actually doesn't even work the same because all of the
defined f* methods will use the same "i" because "i" is not
local for each iteration for "for" but it is for #each using a
normal block.
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
.
- Follow-Ups:
- Re: Help! define_method leaking procs...
- From: Ara.T.Howard
- Re: Help! define_method leaking procs...
- From: ts
- Re: Help! define_method leaking procs...
- References:
- Re: Help! define_method leaking procs...
- From: Yohanes Santoso
- Re: Help! define_method leaking procs...
- Prev by Date: Re: Unit Testing with REXML questions
- Next by Date: Re: Help! define_method leaking procs...
- Previous by thread: Re: Help! define_method leaking procs...
- Next by thread: Re: Help! define_method leaking procs...
- Index(es):
Relevant Pages
|