Proxy.isProxyClass scalability

Peter Levart peter.levart at
Thu Jan 24 13:49:56 UTC 2013


Recently I stumbled upon the scalability problem of 
j.l.r.Proxy.isProxyClass(Class) method when trying to find-out why the 
equals() method of annotations is not scalable. The reason is that 
j.l.r.Proxy uses a single synchronized wrapper around WeakHashMap to 
keep track of proxy classes in order to implement isProxyClass method:

  244     /** set of all generated proxy classes, for isProxyClass implementation */
  245     private static Map<Class<?>, Void> proxyClasses =
  246         Collections.synchronizedMap(new WeakHashMap<Class<?>, Void>());

  631     public static boolean isProxyClass(Class<?> cl) {
  632         if (cl == null) {
  633             throw new NullPointerException();
  634         }
  636         return proxyClasses.containsKey(cl);
  637     }

In the discussion on the cuncurrency-interest list:

* was indicated that other places in JDK besides the annotation's 
equals() method suffer from this scalability bottleneck, mainly in the 
field of serialization, RMI and JMX.

With the help from this discussion, I prepared a possible fix which I'm 
proposing here:

The fix drops usage of synchronized wrapper and WeakHashMap and replaces 
them with a ClassValue and a little ThreadLocal trick to initialize it. 
The ThreadLocal trick could be replaced with a simple static variable 
guarded by a synchronized block if desired.

I have some results from a micro-benchmark that exercises the 
annotation's equals method. The results were obtained on two different 


The benchmark sources:


Thanks to Aleksey Shipilev for showing me the obvious pitfalls when 
designing a micro-benchmark. I hope this time it does the job correctly...

What do you thik? Should I file a RFE first?

Regards, Peter

More information about the core-libs-dev mailing list