bottleneck by java.lang.Class.getAnnotations() - proposed patch
Martin Buchholz
martinrb at google.com
Wed Nov 7 19:13:07 UTC 2012
On Wed, Nov 7, 2012 at 11:02 AM, Peter Levart <peter.levart at gmail.com>wrote:
> On 11/07/2012 06:59 PM, Martin Buchholz wrote:
>
> We've also seen deadlocks in accessing annotations in the wild.
> So, many thanks for working on this (both performance improvements and
> deadlock removal).
> We don't have a test case to contribute, but here's a stacktrace:
>
> That's one thread. What about the other(s)?
>
> sun.reflect.annotation.AnnotationType.getInstance(Annotation
Type.java:80)
sun.reflect.annotation.AnnotationParser.parseAnnotation
(AnnotationParser.java:220)
sun.reflect.annotation.AnnotationParser.parseAnnotations2
(AnnotationParser.java:87)
sun.reflect.annotation.AnnotationParser.parseAnnotations
(AnnotationParser.java:70)
java.lang.Class.initAnnotationsIfNecessary(Class.java:3093)
java.lang.Class.getAnnotation(Class.java:3050)
sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:130)
sun.reflect.annotation.AnnotationType.getInstance(Annotation
Type.java:83)
sun.reflect.annotation.AnnotationParser.parseAnnotation
(AnnotationParser.java:220)
sun.reflect.annotation.AnnotationParser.parseAnnotations2
(AnnotationParser.java:87)
sun.reflect.annotation.AnnotationParser.parseAnnotations
(AnnotationParser.java:70)
java.lang.Class.initAnnotationsIfNecessary(Class.java:3093)
java.lang.Class.getAnnotation(Class.java:3050)
sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:130)
sun.reflect.annotation.AnnotationType.getInstance(Annotation
Type.java:83)
sun.reflect.annotation.AnnotationParser.parseAnnotation
(AnnotationParser.java:220)
sun.reflect.annotation.AnnotationParser.parseAnnotations2
(AnnotationParser.java:87)
sun.reflect.annotation.AnnotationParser.parseAnnotations
(AnnotationParser.java:70)
java.lang.reflect.Field.declaredAnnotations(Field.java:1034)
java.lang.reflect.Field.getAnnotation(Field.java:1018)
> I guess this is similar to http://bugs.sun.com/view_bug.do?bug_id=7122142
>
> Various locks are involved:
>
> - AnnotationType.getInstance is a static synchronized method (locks on
> AnnotationType.class)
>
> - Class.initAnnotationsIfNecessary is an instance synchronized method
> (locks on various .class instances)
>
> lazy initialization sequence can take various ordering combinations among
> threads (recursing on loading annotations on annotations - the meta
> annotations - when requested by the AnnotationType init).
>
> The proposed patch removes blocking synchronization on
> Class.initAnnotationsIfNecessary (replacing this method with another one
> that has no blocking synchronization). Therefore just one lock remains in
> such scenarios (AnnotationType.getInstance) and there's no dead-lock with
> just one lock ;-)
>
I haven't actually tried to fix it, but I've thought about it, also
thinking about replacing locks with lazy lock-free initialization, probably
using Unsafe to cas class metadata.
More information about the core-libs-dev
mailing list