peter.levart at gmail.com
Wed Apr 24 07:13:31 UTC 2013
On 04/24/2013 07:33 AM, Mandy Chung wrote:
> 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.
But! If the interface in the sub-key (the CacheKey in WeakCache is the
1st-level key and is a WeakReference<ClassLoader>, the sub-key holds
interfaces or interface names) happens to be loaded by the same
ClassLoader as the proxy class, the ClassLoader will never be GC-ed and
consequently the ClassValue will never be cleared and the entry will
never be expunged... We have to wrap with a WeakReference:
- the ClassLoader
- each individual interface Class object
- proxy Class object
All 3 types of objects can have implicit or explicit strong references
> 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
>> 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?
More information about the core-libs-dev