Jdk动态代理源码缓存优化比较(JDK17比JDK8)
目录
JDK 8的缓存实现
JDK 17的缓存实现
优化比较
总结实际应用影响
JDK 8的缓存实现
// JDK 8
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache =
new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
在JDK8中使用WeakCache存储代理类,key是ClassLoader和接口数组的组合,value是生成的代理类Class对象
JDK 17的缓存实现
// JDK 17
private static final ClassLoaderValue<Constructor<?>> proxyCache =
new ClassLoaderValue<>();
优化比较
我们可以进行以下的比较
// JDK 8缓存代理类
WeakCache<ClassLoader, Class<?>[], Class<?>>
// JDK 17直接缓存构造器
ClassLoaderValue<Constructor<?>>
// JDK 8
Class<?> proxyClass = proxyClassCache.get(loader, interfaces);
Constructor<?> cons = proxyClass.getConstructor(constructorParams);
// JDK 17
Constructor<?> cons = proxyCache.sub(intf).computeIfAbsent(...);
JDK 8是缓存Class对象,而JDK 17是直接缓存Constructor,避免额外的反射调用。
而且在JDK17还对单接口和多接口实现再次进行了优化
// 单接口
proxyCache.sub(intf) // 使用接口Class作为key创建子缓存
.computeIfAbsent( // 在子缓存中查找或计算
loader, // 使用ClassLoader作为key
(ld, clv) -> new ProxyBuilder(ld, clv.key()).build() // 缓存未命中时的计算逻辑
)
// 多接口
proxyCache.sub(intfs) // 使用接口List作为key创建子缓存
.computeIfAbsent(...) // 同上
多重优化提供了更轻量级的缓存实现
总结实际应用影响
高并发场景:更快的代理对象创建速度,避免额外的反射调用
内存敏感场景:更少的内存占用,减少内存泄露的风险