Details
-
Bug
-
Resolution: Unresolved
-
P4
-
11
-
None
Description
ClassInfo keeps classes in SoftReferences which is unreasonable.
When a Class is no longer reachable, there is no reason to keep it until the memory runs out.
A Weak Key is therefore sufficent.
A Weak Value would probably also be more reasonable, but that's discussable, contrary to the key.
Probably, other useages of com.sun.beans.util.Cache might have similar issues
Workaround is to change the reference type via reflection.
protected Field makeFinalFieldAccessible(Field field) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
return field;
}
protected void fixLeakInBeansCache() {
try {
Class classinfo = getClass().getClassLoader().loadClass("com.sun.beans.introspect.ClassInfo");
Field cacheField = classinfo.getDeclaredField("CACHE");
cacheField.setAccessible(true);
//cacheField.setInt(cacheField, cacheField.getModifiers() & ~Modifier.FINAL/* & ~Modifier.PRIVATE*/);
Object cache = cacheField.get(null);
Class kind = getClass().getClassLoader().loadClass("com.sun.beans.util.Cache$Kind");
Object weak = kind.getDeclaredField("WEAK").get(null);
System.out.println("Cache: " + cache);
System.out.println("kind: " + kind);
Field field1 = makeFinalFieldAccessible(cache.getClass().getSuperclass().getDeclaredField("keyKind"));
Field field2 = makeFinalFieldAccessible(cache.getClass().getSuperclass().getDeclaredField("valueKind"));
field1.set(cache,weak);
field2.set(cache,weak);
Field crfField = ConcurrentReferenceHashMap.class.getDeclaredField("DEFAULT_REFERENCE_TYPE");
makeFinalFieldAccessible(crfField);
crfField.set(null, ConcurrentReferenceHashMap.ReferenceType.WEAK);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
When a Class is no longer reachable, there is no reason to keep it until the memory runs out.
A Weak Key is therefore sufficent.
A Weak Value would probably also be more reasonable, but that's discussable, contrary to the key.
Probably, other useages of com.sun.beans.util.Cache might have similar issues
Workaround is to change the reference type via reflection.
protected Field makeFinalFieldAccessible(Field field) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
return field;
}
protected void fixLeakInBeansCache() {
try {
Class classinfo = getClass().getClassLoader().loadClass("com.sun.beans.introspect.ClassInfo");
Field cacheField = classinfo.getDeclaredField("CACHE");
cacheField.setAccessible(true);
//cacheField.setInt(cacheField, cacheField.getModifiers() & ~Modifier.FINAL/* & ~Modifier.PRIVATE*/);
Object cache = cacheField.get(null);
Class kind = getClass().getClassLoader().loadClass("com.sun.beans.util.Cache$Kind");
Object weak = kind.getDeclaredField("WEAK").get(null);
System.out.println("Cache: " + cache);
System.out.println("kind: " + kind);
Field field1 = makeFinalFieldAccessible(cache.getClass().getSuperclass().getDeclaredField("keyKind"));
Field field2 = makeFinalFieldAccessible(cache.getClass().getSuperclass().getDeclaredField("valueKind"));
field1.set(cache,weak);
field2.set(cache,weak);
Field crfField = ConcurrentReferenceHashMap.class.getDeclaredField("DEFAULT_REFERENCE_TYPE");
makeFinalFieldAccessible(crfField);
crfField.set(null, ConcurrentReferenceHashMap.ReferenceType.WEAK);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
Attachments
Issue Links
- relates to
-
JDK-8231454 File lock in Windows on a loaded jar due to a leak in Introspector::getBeanInfo
- Resolved