On Mon, 15 Nov 2021 21:35:06 GMT, Roman Kennke <rken...@openjdk.org> wrote:

>> The caches in ObjectStreamClass basically map WeakReference<Class> to 
>> SoftReference<ObjectStreamClass>, where the ObjectStreamClass also 
>> references the same Class. That means that the cache entry, and thus the 
>> class and its class-loader, will not get reclaimed, unless the GC determines 
>> that memory pressure is very high.
>> 
>> However, this seems bogus, because that unnecessarily keeps ClassLoaders and 
>> all its classes alive much longer than necessary: as soon as a ClassLoader 
>> (and all its classes) become unreachable, there is no point in retaining the 
>> stuff in OSC's caches.
>> 
>> The proposed change is to use WeakReference instead of SoftReference for the 
>> values in caches.
>> 
>> Testing:
>>  - [x] tier1
>>  - [x] tier2
>>  - [x] tier3
>>  - [ ] tier4
>
> Roman Kennke has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - Use ForceGC instead of System.gc()
>  - Convert test to testng

> While it is true that when the Class object used in a weak key is not 
> reachable any more by the app, it is not sensible to hold on to the value any 
> longer so in that respect SoftReference is to "storng" of a weakness. But 
> while the Class object is still reachable by the app, the app expects to 
> obtain the ObjectStreamClass (the value) from the cache at least most of the 
> time. If you change the SoftReference into WeakReference, the 
> ObjectStreamClass might get GC-ed even while in the middle of stream 
> deserialization.

I don't quite understand this: If the Class object is still reachable by the 
app, 1. a weak reference would not get cleared and 2. the Class's ClassLoader 
would not get unloaded. Conversely, if it's not reachable by the app anymore, 
then the *key* in the cache would get cleared, and we would not find the 
ObjectStreamClass anyway. Except that the OSC holds onto the Class object by a 
SoftReference, so it would effectively prevent getting cleared (and get 
unloaded).

> ObjectStream class pre-dates java.lang.invoke (MethodHandles), so it uses its 
> own implementation of weak caching. But since MethodHandles, there is a class 
> called ClassValue that would solve these problem with more elegance, because 
> it ties the lifetime of the value (ObjectStreamClass) to the lifetime of the 
> Class key (Class object has a strong reference to the associated value) while 
> the Class key is only Weakly referenced.

Hmm, sounds nice. Do you think that would work in the context of OSC?

-------------

PR: https://git.openjdk.java.net/jdk/pull/6375

Reply via email to