You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2024/01/08 15:37:19 UTC

(groovy) 01/01: GROOVY-11271: ConcurrentCommonCache causes memory leaks

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY-11271
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit c8a02e4e4d89fe4303b1427d388791139c1963b2
Author: Daniel Sun <su...@apache.org>
AuthorDate: Mon Jan 8 23:37:04 2024 +0800

    GROOVY-11271: ConcurrentCommonCache causes memory leaks
---
 .../codehaus/groovy/runtime/memoize/CommonCache.java   | 18 ++++++++++++++++--
 .../runtime/memoize/ConcurrentCommonCacheTest.java     |  2 +-
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/memoize/CommonCache.java b/src/main/java/org/codehaus/groovy/runtime/memoize/CommonCache.java
index cf231a4614..3701f44e31 100644
--- a/src/main/java/org/codehaus/groovy/runtime/memoize/CommonCache.java
+++ b/src/main/java/org/codehaus/groovy/runtime/memoize/CommonCache.java
@@ -19,6 +19,8 @@
 
 package org.codehaus.groovy.runtime.memoize;
 
+import org.apache.groovy.util.concurrent.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
+
 import java.io.Serializable;
 import java.lang.ref.SoftReference;
 import java.lang.ref.WeakReference;
@@ -64,14 +66,26 @@ public class CommonCache<K, V> implements EvictableCache<K, V>, ValueConvertable
      * @param evictionStrategy LRU or FIFO, see {@link org.codehaus.groovy.runtime.memoize.EvictableCache.EvictionStrategy}
      */
     public CommonCache(final int initialCapacity, final int maxSize, final EvictionStrategy evictionStrategy) {
-        this(new LinkedHashMap<K, V>(initialCapacity, DEFAULT_LOAD_FACTOR, EvictionStrategy.LRU == evictionStrategy) {
+        this(createMap(initialCapacity, maxSize, evictionStrategy));
+    }
+
+    private static <K, V> Map<K, V> createMap(int initialCapacity, int maxSize, EvictionStrategy evictionStrategy) {
+        final boolean lru = EvictionStrategy.LRU == evictionStrategy;
+
+        if (lru) {
+            return new ConcurrentLinkedHashMap.Builder<K, V>()
+                        .initialCapacity(initialCapacity)
+                        .maximumWeightedCapacity(maxSize)
+                        .build();
+        }
+        return new LinkedHashMap<K, V>(initialCapacity, DEFAULT_LOAD_FACTOR, lru) {
             private static final long serialVersionUID = -8012450791479726621L;
 
             @Override
             protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
                 return size() > maxSize;
             }
-        });
+        };
     }
 
     /**
diff --git a/src/test/org/codehaus/groovy/runtime/memoize/ConcurrentCommonCacheTest.java b/src/test/org/codehaus/groovy/runtime/memoize/ConcurrentCommonCacheTest.java
index efbb054a4b..9eef22e4b7 100644
--- a/src/test/org/codehaus/groovy/runtime/memoize/ConcurrentCommonCacheTest.java
+++ b/src/test/org/codehaus/groovy/runtime/memoize/ConcurrentCommonCacheTest.java
@@ -178,7 +178,7 @@ public class ConcurrentCommonCacheTest {
         sc.put("c", "3");
         sc.put("a", "4");
         sc.put("d", "5");
-        Assert.assertArrayEquals(new String[] {"c", "a", "d"}, sc.keys().toArray(new String[0]));
+        Assert.assertEquals(3, sc.size());
         Assert.assertEquals("3", sc.get("c"));
         Assert.assertEquals("4", sc.get("a"));
         Assert.assertEquals("5", sc.get("d"));