-
Notifications
You must be signed in to change notification settings - Fork 91
Open
Description
The implementation of ClassByNameCache
appears to cause class leaks by failing to properly clean up FutureValue
references on the failure path where the loader is not "the system loader". This seems to cause two symptoms:
- Singular classes (highly unlikely to be defined multiple times) that are loaded by the either the platform loader, or the bootstrap loader are left in the cache, indirecting through
FutureValue
instances on every lookup. This is harmless but is probably costing some tiny amount of performance:

- Classes loaded by custom class loaders that need to be unloadable cannot be since the ClassByNameCache is strongly referencing one of the loaded classes that has been pulled through serialization.

The trivial fix to 2 is purge the cache key on seeing a "non-system loader" in the update method:
diff --git a/closed/src/java.base/share/classes/java/io/ClassByNameCache.java b/closed/src/java.base/share/classes/java/io/ClassByNameCache.java
index 332caec9675..e8e3801c145 100644
--- a/closed/src/java.base/share/classes/java/io/ClassByNameCache.java
+++ b/closed/src/java.base/share/classes/java/io/ClassByNameCache.java
@@ -116,6 +116,7 @@ void update(CacheKey key, Class<?> result) {
Object resultLoaderObj =
LoaderRef.getLoaderObj(result.getClassLoader());
if (getCanonicalLoaderRef(resultLoaderObj).isSystem == false) {
+ cache.remove(key);
return;
}
This will have the unfortunate side-effect of negating the performance benefit of the class caching for the bulk of the JDK standard library classes. A complete fix would be to also enhance the loader check to take in to account all three of the "special" loaders: system, platform and bootstrap.
Metadata
Metadata
Assignees
Labels
No labels