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