Using strong value references in STATIC_CODECS cache leads to target
classes being strongly reachable through the codec itself -- hence
they will never be weakly reachable, hence they will not be GC'd.
Use soft values, which allows the classes to be GC'd as soon as the
JVM decides they have not been used for a while -- which is what
will happen when a class becomes almost-eligible for unloading.
JIRA: MDSAL-580
Change-Id: I7956d564c46a9a1d52ba85fbe61f3a19c507a902
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit
0150ddd6c4e3c61a761dacb9161e84b3f38b748a)
* Value codec, which serializes / deserializes values from DOM simple values.
*/
abstract class ValueTypeCodec implements Codec<Object, Object> {
* Value codec, which serializes / deserializes values from DOM simple values.
*/
abstract class ValueTypeCodec implements Codec<Object, Object> {
-
- private static final Cache<Class<?>, SchemaUnawareCodec> STATIC_CODECS = CacheBuilder.newBuilder().weakKeys()
- .build();
+ /*
+ * Use identity comparison for keys and allow classes to be GCd themselves.
+ *
+ * Since codecs can (and typically do) hold a direct or indirect strong reference to the class, they need to be also
+ * accessed via reference. Using a weak reference could be problematic, because the codec would quite often be only
+ * weakly reachable. We therefore use a soft reference, whose implementation guidance is suitable to our use case:
+ *
+ * "Virtual machine implementations are, however, encouraged to bias against clearing recently-created or
+ * recently-used soft references."
+ */
+ private static final Cache<Class<?>, SchemaUnawareCodec> STATIC_CODECS = CacheBuilder.newBuilder()
+ .weakKeys().softValues().build();
/**
* Marker interface for codecs, which functionality will not be affected by schema change (introduction of new YANG
/**
* Marker interface for codecs, which functionality will not be affected by schema change (introduction of new YANG
* binary, strings and empty.
*/
public static final SchemaUnawareCodec NOOP_CODEC = new SchemaUnawareCodec() {
* binary, strings and empty.
*/
public static final SchemaUnawareCodec NOOP_CODEC = new SchemaUnawareCodec() {
@Override
public Object serialize(final Object input) {
return input;
@Override
public Object serialize(final Object input) {
return input;
EncapsulatedValueCodec.loader(typeClz, typeDef));
return new CompositeValueCodec(extractor, delegate);
}
EncapsulatedValueCodec.loader(typeClz, typeDef));
return new CompositeValueCodec(extractor, delegate);
}