Unreferenced object not garbage collected

I am currently hunting down a memory leak in Kelvin Kazoom (http://www.digitprop.com/kazoom/index.html), and have come across a strange phenomenon:

I have app. 20 objects in a Hashtable. I clear() the hash table and am pretty sure that there are no other references to these objects (from looking at the code, and from the very useful Reference Scanner - http://jb2works.com/refscan/usage.html).

If I now create WeakReferences on all these objects before clear()'ing the map, then run the garbage collector (via System.gc()), all the WeakReferences show null references (i.e. the objects have been gc’ed) except for the object last returned by the Hashtable’s keys() enumeration.

Has anybody come across something similar? I know that System.gc() is not guaranteed to do anything, but find it very strange that everything is gc’ed except for one object.

When I wait a few seconds, then have a second look, the one remaining object is also eventually gc’ed.

One more detail: Reference Scanner correctly shows the uncollected object, but no references to it. So it seems like the object is not in the GC queue for some reason, but has no references whatsoever.

You’re obviously going to need to show us some code.
Garbage collection occurs only on the objects that are not being used.

A couple of possiblities I can think of:

  1. Since Reference Scanner operates as a dameon thread in your app, perhaps it is actually referencing the remaining entry in some way?

  2. You may be witnessing an optimization of some kind.

Either way, it’s only one object, then it gets GC’d. Is it really a big deal or is the investigation purley academic?

Thanks for the answers!

KILER: I know that code would be helpful, but it’s much too much code; I have already tried to reproduce it in a small test class, but that doesn’t work. Obviously the problem ‘needs’ the complex memory allocation of the application.

I know that the obvious explanation would be a reference I missed. Therefore I tried to look as diligently as possible before posting this.

Vorax: You are probably right in that this is some kind of optimization. And no, it’s no big deal and more of an academic question. Also, I thought this may be interesting for others - I have wasted quite some time tracking down a missed reference, because I assumed that after System.gc() every non-referenced object would be cleared.

I know that the method is not meant to guarantee this, but this is what I have seen so far when I investigated memory problems.

The gc is a generational one. So it only collects objects that are a certain age. Since the one not being collected had the last reference to it released, it is probably just not flagged for gc yet.

[quote]The gc is a generational one. So it only collects objects that are a certain age. Since the one not being collected had the last reference to it released, it is probably just not flagged for gc yet.
[/quote]
Ah, that makes sense. I guess things aren’t quite as simple as I thought them to be…