On Aug 22, 2008, at 10:34, Jeremias Maerki wrote:
On 22.08.2008 00:15:00 Andreas Delmelle wrote:
So, I was wondering about the role of the reference queue. Calling
poll() returns the first reference /if/ one is available, so it seems
likely that cleanSegment() does get called frequently enough, but
there's always the possibility that it returns without a reference
being available, yet. Or, as it happens, after throwing away only
roughly half of the references.
Maybe it's only those that are also effectively enqueued at the time
the cleanup is triggered (didn't try adding this to the stats yet).
Javadoc says about WeakReference that the queueing may happen at some
point after the reference is cleared. But a delay alone doesn't
that so many instances weren't cleared.
I got the impression that the cleaning wasn't done for some cache
segments at all because the threshold never got reached. Just a
Now I suddenly see it... Due to what you point out below, some
entries in bucket #0 will be distributed over the reference queueS
(plural) for segments #0, #8, #16 and #24, but each cleanup only
takes care of one of those 4 segments (the one where the entry ended
up that was last added in put()).
Segments: always 32
Buckets: initially 8, rehash doubles the number of buckets each time
That doesn't match what you're saying. Initially, 4 segments would
entries in 1 bucket. After a few rehashes, each segment would have its
entries in a set of buckets. I think that's why in your patch the
segment.count goes down into the negative (i.e. it's wrong).
Correct. No idea why I never saw that... :/
The effect of the count going into the negative follows from the fact
that some stale entries will actually belong to another segment. The
only other way around that would have been to always limit the number
of segments to table.length [i.e. the segmentIndex for a lower number
of buckets should actually have been something like: hash(o) &
((SEGMENT_COUNT - 1) & (table.length - 1))], so that all entries for
one bucket always belong to the same segment. My patch
unconditionally cleared the whole bucket, decreasing the count for
the wrong segment.
Plus, the removal of the reference queue polling just queues up
references which are never cleared. I've fixed that locally.
Darn', I thought I had modified the constructor to not register the
entry with the queue. Seems I undid that change at some point...