Proxy.isProxyClass scalability

Peter Levart peter.levart at gmail.com
Thu Jan 24 15:45:57 UTC 2013


On 01/24/2013 03:40 PM, Vitaly Davidovich wrote:
>
> Peter,
>
> I know this was brought up on your c-i mailing list thread, but it 
> really feels like a new boolean field in j.l.Class is the cleaner 
> solution (and infinitely scalable and doesn't require bookkeeping in 
> the Proxy class).  Is there really no existing alignment gap in 
> j.l.Class layout that a boolean can slide into?
>
There might be, I will check. The ClassValue is scalable too (check the 
benchmarks), and bookkeeping is performed in the 
ClassValue.ClassValueMap that is referenced from the Class - not in the 
Proxy class. Unfortunately the j.l.r.Proxy class is in another package 
from j.l.Class, so the solution with a simple boolean field would 
require JavaLangAccess or Unsafe acrobatics.

Another thing is this separate bug:

http://bugs.sun.com/view_bug.do?bug_id=7123493

To solve it, a reference field in j.l.ClassLoader or a hypothetical 
ClassLoaderValue implementation would be required. I looked at the bug 
reporter's solution (ConcurrentProxy). He guards the 
WeakHashMap<ClassLoader, ...> with a ReadWriteLock:

/*
* Find or create the proxy class cache for the class loader.
*/
Map<Object,Reference<Class>> cache;
try{
loaderToCacheLock.readLock().lock();
cache = loaderToCache.get(loader);
}finally{
loaderToCacheLock.readLock().unlock();
}
// window of opportunity here between locks that would result in 
duplicate put(..) call
if (cache == null) {
try{
loaderToCacheLock.writeLock().lock();
cache = new ConcurrentHashMap<Object,Reference<Class>>();
loaderToCache.put(loader, cache);
}finally{
loaderToCacheLock.writeLock().unlock();
}
}


That code is broken twice. First, it is not double-checking the 
existence of cache in the writeLock guarded section. That's not so 
serious and could be fixed.
The other fault is using ReadWriteLock.readLock() to guard the 
WeakHashMap.get(). This is dangerous, since WeakHashMap.get() is a 
mutating method (expunging stale entries).

I don't think fixing this bug without either:
- new field in ClassLoader or
- ClassLoaderValue or
- WeakConcurrentHashMap

...is possible. Since we don't have the later two at the moment, the 
best bet for it unfortunately seems to be the first solution.

Regards, Peter

> Sent from my phone
>
> On Jan 24, 2013 9:35 AM, "Peter Levart" <peter.levart at gmail.com 
> <mailto:peter.levart at gmail.com>> wrote:
>
>     On 01/24/2013 03:10 PM, Alan Bateman wrote:
>
>         On 24/01/2013 13:49, Peter Levart wrote:
>
>             Should I file a RFE first?
>
>         Sorry I don't have time at the moment to study the proposed
>         patch but just to mention that it has come up a few times, its
>         just that it never bubbled up to the top of anyone's list.
>         Here's the bug tracking it:
>
>         http://bugs.sun.com/view_bug.do?bug_id=7123493
>
>         -Alan.
>
>     I belive that is another bottleneck. It is mentioning the
>     Proxy.getProxyClass method which also uses synchronization for
>     maintaining a cache of proxy classes by request parameters. I
>     could as well try to fix this too in the same patch if there is
>     interest.
>
>     Regards, Peter
>




More information about the core-libs-dev mailing list