I read the code in the prototype and I liked what I saw (even excited!), which 
is the reason I spoke up.

On the API side, I was mulling over what the addition of bulk methods and even 
just a size() method could do to help and it struck me: the JDK has come a long 
way since 1.0 and there are now fully fledged, well thought out queue 
implementations. Is there a reason ReferenceQueue can't be upgraded to be one 
of those (api and/or implementation wise)?

I hope given all the reasoning that's gone into the canonical queue 
implementations there wouldn't be a lot of reason to debate their usefulness. 
But just as an example, let's consider having access to a fast, roughly 
accurate ReferenceQueue.size() method for the hash structures use case.  A hash 
structure has to find the freed instances and remove them. If size() returns a 
large portion of the total entries, it would be better to re-hash the structure 
and bulk clear the references instead.

Unfortunately, I don't have a great benchmark, so I can't run the prototype 
quickly. I'll have to put some time aside to figure out a good way to represent 
the situation before I can come back with meaningful numbers.

Thanks
Moh

From: Peter Levart [mailto:peter.lev...@gmail.com]
Sent: Monday, June 01, 2015 5:04 AM
To: Rezaei, Mohammad A. [Tech]
Cc: 'hotspot-gc-...@openjdk.java.net openjdk.java.net'; 
'core-libs-dev@openjdk.java.net'
Subject: Re: JEP 132: More-prompt finalization

Hi Moh,
On 06/01/2015 04:42 AM, Rezaei, Mohammad A. wrote:
The problems start with the ReferenceQueue object and the heavy synchronization 
in it. Consider structures like j.u.WeakHashMap that need to expunge entries. 
If such structures are made somewhat concurrent, the lock in ReferenceQueue 
starts to become a serious problem:

-          In structures that are concurrent at the entry level (like jdk 8's 
ConcurrentHashMap), if methods like get() or put() try to expunge, the lock in 
ReferenceQueue renders the structures non-concurrent.

The presented prototype changes the implementation of ReferenceQueue. It 
doesn't use a lock any more for enqueu-ing when there are no waiters and never 
for poll-ing. ReferenceQueue.poll() is a single volatile read when queue is 
empty and a read followed by CAS when it is not (with retries when contended). 
If there is a desire and new API could be extended, the method like the 
following:

Iterator<Reference<? extends T>> pollChunk(int maxChunkSize);

...could return a chunk of enqueued references (or an empty iterator) so that 
the reduced number of CAS instructions per de-queued reference could be traded 
for the greater probability of retries because of contention.



-          In structures that are multi-reader-single-writer locked, read 
methods cannot expunge (because they have to promote to a writer), but they 
can't even check the queue, because that turns the multi-reader structure into 
a synchronized one.

By checking you mean poll() which also de-queues a reference if available? What 
do you do when this happens. Would you need a peek() method maybe?



-          In addition to expunge calls contending on the ReferenceQueue lock, 
ReferenceHandler thread can also contend on the same lock.

That's right. And in the presented prototype, this is minimized by allowing 
ReferenceHandler thread to enqueue a chunk of pre-prepared references in one 
go, minimizing the need to frequently notify any possible waiters via a 
lock.notifyAll().



-          There is no fast clear() method on ReferenceQueue. That would be 
quite useful on a resize event.

This would be easy to implement if new API could be added.



The above issues forced us to have a dedicated thread that does periodic 
expunging of References. This works ok under light load, but can fall behind 
under heavy load.

Because of the overhead/bottleneck of the reference processing I assume. It 
would be great if you could check whether the prototype in webrev.02 improves 
your situation. It should be simple. Just compile the sources and prepend the 
resulting classes to the bootclasspath of the JDK.

Regards, Peter



Thanks
Moh


@Moh

Can you elaborate some more on what twists were necessary or what problems you 
had?





Reply via email to