In message [email protected], dima
[email protected] writes
If you keep a reference to some object is something you do on
purpose.
Unless there is an error in your logic. Perhaps you forgot to clear the
reference(s) to the object when you were finished with it? Perhaps the
design changed and you forgot to clear the reference, or forgot to call
a method that cleared the reference.
No different to a memory leak in a non-garbage collected language.
Engineers don’t put errors in programs deliberately (well, if you’ve got
one, you need to sack them), they happen by mistake, design error,
tiredness, Friday afternoons, etc. Thats life, stuff happens.
That is why since Java came on the scene companies like Sitraka (with
JProbe in 1996) and many others since have produced tools to detect such
situations. Its also why we created Ruby Memory Validator, because such
problems do exist for some applications.
The main problem with leaks in garbage collected programs is that by
their very nature (an unwanted reference is held) they are harder to
detect than for non-garbage collected programs.
The statement you write above makes me think you have not truly
experienced a memory leak situation in a GC’d application (regardless of
language - the principles remain the same).
I mention Sitraka as they were the first company I am aware of that
released a commercial tool for this task. They also published an article
in Dr Dobbs detailing their position on this area and the terms they
used. They called an unwanted object a “loiterer” if I recall correctly.
There were three types:
o Unwanted object references held longer than necessary by accident (the
typical memory leak scenario). This reference could be stored in a
static data member (class member) or in a dynamic data member (instance
member)
o Temporary object on stack held for longer than necessary, preventing
potentially large object trees from being collected
someFunc()
{
obj = createALargeNumerOfObjectsAndGiveMeTheRoot();
doSomeWork(obj);
doSomeOtherWorkThatCouldDoWithMemoryReclaim();
}
obj could be reclaimed after doSomeWork() (assuming the stack ref is the
only reference to it) but because it is on the stack it can’t be. A
better way to do this would be to create a local scope for it (yes,
there are other variantions, this is just to demo the point)
someFunc()
{
{
obj = createALargeNumerOfObjectsAndGiveMeTheRoot();
doSomeWork(obj);
}
doSomeOtherWorkThatCouldDoWithMemoryReclaim();
}
o Some other case I can’t recall right now (sorry I have a horrible cold
and don’t feel so good, so memory not working so good…). I’m pretty
sure there was a third case, but it eludes me. Sorry.
It quite interesting watching the Ruby community have the same
discussions (and same misconceptions) about memory as happened in the
Java community over a decade ago.
I’ve found a reference to Sitraka’s work here: Its a powerpoint
presentation. For all of you that think memory leaks can’t happen in a
GC’d environment please take a look. Its a not a leak in the terms of a
C memory leak, but you are still chewing through memory.
These are different presentations, found using a simple Google search:
http://www.java-forum-stuttgart.de/jfs/2001/folien/C2.ppt
http://java.quest.com/JUG/meetings/presentations/sep02/JUG%20Sept%202002.
PPT
I hope you find them interesting. They apply to Ruby just as much as
they do to Java.
Stephen