RFR JDK-8011940 : java.lang.Class.getAnnotations() always enters synchronized method
Peter Levart
peter.levart at gmail.com
Wed Aug 7 16:18:05 UTC 2013
Hi,
I propose a patch for the following and related bugs:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8011940
Here's the 1st webrev:
http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationData/webrev.01/
The patch eliminates classic synchronization by using optimistic
concurrent construction. At the end of construction, the "winning"
result is installed using CAS. The solution is modelled upon the similar
solution used to cache reflection data. Both annotations Maps and a
redefinedCount int are grouped in a container AnnotationData object
which is referenced with a single volatile field. Not using any locks
also solves potential deadlock situations described in a related bug:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7122142
That bug has already been closed with a fix for AnnotationType
construction and caching:
http://hg.openjdk.java.net/jdk8/tl/jdk/rev/e4ce6502eac0
So the alternative solution for scalability problem is using
double-checked locking instead of CAS should concurrent initial requests
for annotations be a problem (CPU usage).
Micro benchmark shows about 5x improvement in raw single-threaded speed
of retrieving an annotation by type and linear scalability:
http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationData/test_results1.txt
The space consumption is different with the patch. Initially j.l.Class
objects are smaller, since one int and one reference field are
eliminated from the j.l.Class. If annotations are requested the overhead
is the AnnotationData container object and the field to reference it.
But I tried to be smarter than the original code and when there's no
inherited annotations (common situation), the annotations and
declaredAnnotations share the same Map instance (originally new HashMap
instance was constructed and entries copied). When there's no
annotations declared on the class and no inherited annotations, this
shared Map instance is an Collections.emptyMap() singleton.
Regards, Peter
More information about the core-libs-dev
mailing list