RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v4]
vlivanov at openjdk.java.net
Fri Sep 3 18:54:40 UTC 2021
On Fri, 3 Sep 2021 14:41:45 GMT, Vladimir Ivanov <vlivanov at openjdk.org> wrote:
>> `MethodHandle.asTypeCache` keeps a strong reference to adapted `MethodHandle` and it can introduce a class loader leak through its `MethodType`.
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can only contain `MethodHandle`s which are guaranteed to not introduce any dependencies on new class loaders compared to the original `MethodHandle`. 2nd level is backed by a `SoftReference` and is used as a backup when the result of `MethodHandle.asType()` conversion can't populate the higher level cache.
>> The fix is based on [the work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/) made by Peter Levart @plevart back in 2015.
>> Testing: tier1 - tier6
> Vladimir Ivanov has updated the pull request incrementally with one additional commit since the last revision:
> Address review comments
Other MethodHandle/LambdaForm caches in `java.lang.invoke` deliberately rely on `SoftReference`s. (Only `MethodType` table uses `WeakReference`, but it is there for interning purposes.) MH adaptations are quite expensive (and may involve class loading), so it's beneficial to keep the result around for an extended period of time when circumstances allow.
On the other hand, `MH.asType()` case is special because it can hold user classes around which makes effective memory footprint of cached value much higher. So, `WeakReference` would enable more prompt recycling of heap memory at the expense of higher cache miss rate.
Personally, I'm in favor `SoftReference` here since it allows to get most of performance benefits out of the cache while preserving the correctness w.r.t. heap exhaustion.
More information about the core-libs-dev