Use soft values in ValueTypeCodec 97/91497/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:44:48 +0000 (10:44 +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>
(cherry picked from commit 0150ddd6c4e3c61a761dacb9161e84b3f38b748a)

binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/ValueTypeCodec.java

index 7cf9733607674d4643ea9253d97e64041dfd224b..8c5a1c9009beaccc625371ca4e2e7d8510183c2a 100644 (file)
@@ -21,9 +21,18 @@ import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
  * 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
@@ -38,7 +47,6 @@ abstract class ValueTypeCodec implements Codec<Object, Object> {
      * binary, strings and empty.
      */
     public static final SchemaUnawareCodec NOOP_CODEC = new SchemaUnawareCodec() {
-
         @Override
         public Object serialize(final Object input) {
             return input;
@@ -88,5 +96,4 @@ abstract class ValueTypeCodec implements Codec<Object, Object> {
             EncapsulatedValueCodec.loader(typeClz, typeDef));
         return new CompositeValueCodec(extractor, delegate);
     }
-
 }