BUG-4556: enable DataSchemaContextTrees to be scavenged 94/29094/2
authorRobert Varga <rovarga@cisco.com>
Sun, 1 Nov 2015 12:09:02 +0000 (13:09 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 2 Nov 2015 08:19:03 +0000 (08:19 +0000)
DataSchemaContextTree contains an internal weak-keyed cache, which is
used to speed up lookups and share DataSchemaContextNodes.

Unfortunately the cache uses strong references for values (e.g.
DataSchemaContextTree) instances, which transitively (via
DataSchemaContextNode) retain the reference to the key. This has the
effect of the key being always reachable, thus causing a memory leak.

Make the cache use weak references for values, which ensures that it
gets scavenged whenever its contents are no longer referenced.

Change-Id: I1684d1bf2c2c5cdc44cda1e8e508149ff3a8fae4
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/DataSchemaContextTree.java

index e30b5244883d877e26cdec7052e15f1421e55282..4b80edf6861c8267a787e8f8b14fcb226d7b051f 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.yangtools.yang.data.util;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
-import java.util.Iterator;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
@@ -18,14 +17,11 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public final class DataSchemaContextTree {
     private static final LoadingCache<SchemaContext, DataSchemaContextTree> TREES = CacheBuilder.newBuilder()
-            .weakKeys()
-            .build(new CacheLoader<SchemaContext, DataSchemaContextTree>() {
-
+            .weakKeys().weakValues().build(new CacheLoader<SchemaContext, DataSchemaContextTree>() {
                 @Override
                 public DataSchemaContextTree load(final SchemaContext key) throws Exception {
                     return new DataSchemaContextTree(key);
                 }
-
             });
 
     private final DataSchemaContextNode<?> root;
@@ -40,9 +36,8 @@ public final class DataSchemaContextTree {
 
     public DataSchemaContextNode<?> getChild(final YangInstanceIdentifier path) {
         DataSchemaContextNode<?> currentOp = root;
-        Iterator<PathArgument> arguments = path.getPathArguments().iterator();
-        while (arguments.hasNext()) {
-            currentOp = currentOp.getChild(arguments.next());
+        for (PathArgument arg : path.getPathArguments()) {
+            currentOp = currentOp.getChild(arg);
         }
         return currentOp;
     }