Use soft values in ValueTypeCodec 95/91495/1
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 21 Jul 2020 08:39:32 +0000 (10:39 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 21 Jul 2020 08:42:45 +0000 (10:42 +0200)
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>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ValueTypeCodec.java

index 63cf8de71ccb8feb44af03830ba2c0db19242cec..55e5d1a50c67cc2932e1d8196a9ca787610e1458 100644 (file)
@@ -22,8 +22,18 @@ import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
  */
 // FIXME: IllegalArgumentCodec is perhaps not appropriate here due to null behavior
 abstract class ValueTypeCodec implements IllegalArgumentCodec<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
@@ -39,7 +49,6 @@ abstract class ValueTypeCodec implements IllegalArgumentCodec<Object, Object> {
      * binary, strings and empty.
      */
     public static final SchemaUnawareCodec NOOP_CODEC = new SchemaUnawareCodec() {
-
         @Override
         public Object serialize(final Object input) {
             return input;
@@ -89,5 +98,4 @@ abstract class ValueTypeCodec implements IllegalArgumentCodec<Object, Object> {
             EncapsulatedValueCodec.loader(typeClz, typeDef));
         return new CompositeValueCodec(extractor, delegate);
     }
-
 }