Proxy.isProxyClass scalability

Mandy Chung mandy.chung at
Wed Apr 24 05:33:38 UTC 2013

More comments in addition to what I replied earlier....

On 4/23/2013 4:43 PM, Mandy Chung wrote:
>> Each ClassLoader maintains explicit hard-references to all Class 
>> objects for classes defined by the loader. So proxy Class object can 
>> not be GC-ed until the ClassLoader is GC-ed. 

AFAIU, a class loader will be GC'ed as long as there is no reference to 
any of its loaded classes.  The ClassLoader's internal vector of keeping 
the loaded classes is to prevent the classes from being GC'ed until the 
class loader is being GC'ed which will unload the classes.

So we should make the class loader and the proxy classes weak referenced 
so that they will be GC'ed properly.

>> So we need not register the CacheValue objects in WeakCache with a 
>> refQueue. The expunging of reverseMap entries is already performed 
>> with CacheKey when it is cleared and equeued. There's no harm as it 
>> is, since the clean-up is performed with all the checks and is 
>> idempotent, but it need not be done for ClassValue objects holding 
>> weak references to proxy Class objects.

I actually think we don't need to make CacheKey as a weak reference but 
the CacheValue object should still be registered in the refQueue.  The 
proxy class in the CacheValue implementing the given interfaces always 
reference the interfaces in the CacheKey and it means that the classes 
in the CacheKey will never be GC'ed before the proxy class.   When there 
is no reference to the proxy class, it will be added to the reference 
queue.  Once the entry with the CacheValue holding the proxy class is 
expunged,  the interfaces will not be referenced in the cache.

Does this make sense to you?

> As explained above, for the per-loader proxy class cache, both the key 
> (interfaces) and the proxy class should be wrapped with weak reference.
> In your revisions, you optimize for 0-interface and 1-interface proxy 
> class.  What I hacked up earlier was just to use Class<?>[] as the key 
> (need to make a copy of the array to prevent that being mutated during 
> runtime) that is a simpler and straightforward implementation.  I 
> didn't measure the footprint and compare the performance of your 
> versions.  Have you seen any performance difference which led you to 
> make the recent changes?
> Mandy
> [1] 

More information about the core-libs-dev mailing list