On Nov 12, 2007, at 18:29, Chris Bowditch wrote:
Andreas L Delmelle wrote:
A lot of the code that accesses the ref member variable has
checks for null and since it is a WeakReference I assume the
cause of this error is the Garbage Collector removing the
reference. Adding a check for null in the rehash method seems to
avoid the error and all unit tests pass, but I would like
confirmation from a Properties expert (Andreas?) that this is a
valid fix before committing the change.
If your suggestion fixes the issue, by all means, commit. It
should not hurt to insert a check there.
I'll have a closer look at underlying causes one of the coming days.
Anyway, thanks for spotting this. The possibility of such issues
arising, was precisely the reason I did not include it in the
Thanks for the prompt reply! I've now committed the check for null
in the rehash method.
Good! Just checked the code more closely, and I think your suggestion
is actually the only way to deal with it.
The reason for the NPE seems to be roughly:
- once the size of the hash-chains grows too large, a cleanup-thread
is launched (CacheCleaner), which nulls out the WeakReference if its
referent has been GC'ed, so non-synchronized get() attempts
immediately 'see' that the entry has been removed and get() needs to
try again with synchronization.
- if the size of the cleaned hash-chain is still too large, then the
map is rehashed
Now, the rehash() method obtains locks on all hash-chains
recursively. This means that it is theoretically possible that,
before rehash() obtains the lock on a given map-segment, another
cleaner-thread may have already run over it, and removed some
obsolete entries. Hence why CacheEntry.ref returns null in that case.
As to why this only happens after a few thousand documents: I'd
assume that the size of the hash-chains in that case has grown to a
point where it becomes more and more likely that there are requests
to clean up obsolete references, and those requests can interfere
with a rehash() that resulted from a previous, non-successful cleanup.