This is an automated email from the ASF dual-hosted git repository. sunlan pushed a commit to branch GROOVY-10232 in repository https://gitbox.apache.org/repos/asf/groovy.git
commit a1feedfe8e7bab039a004810cb3edb516af8c44b Author: Daniel Sun <[email protected]> AuthorDate: Sat Oct 23 17:51:16 2021 +0800 GROOVY-10232: Massive increase in memory usage due to CacheableCallSite --- .../groovy/vmplugin/v8/CacheableCallSite.java | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java index a6e4c4c..0e931fa 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java @@ -25,6 +25,7 @@ import org.codehaus.groovy.runtime.memoize.MemoizeCache; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; import java.lang.invoke.MutableCallSite; +import java.lang.ref.SoftReference; import java.util.concurrent.atomic.AtomicLong; /** @@ -34,8 +35,8 @@ import java.util.concurrent.atomic.AtomicLong; */ public class CacheableCallSite extends MutableCallSite { private static final int CACHE_SIZE = SystemUtil.getIntegerSafe("groovy.indy.callsite.cache.size", 16); - private final MemoizeCache<String, MethodHandleWrapper> cache = new LRUCache<>(CACHE_SIZE); - private volatile MethodHandleWrapper latestHitMethodHandleWrapper = null; + private volatile SoftReference<MemoizeCache<String, MethodHandleWrapper>> cacheSoftReference; + private volatile MethodHandleWrapper latestHitMethodHandleWrapper; private final AtomicLong fallbackCount = new AtomicLong(0); private MethodHandle defaultTarget; private MethodHandle fallbackTarget; @@ -45,6 +46,7 @@ public class CacheableCallSite extends MutableCallSite { } public MethodHandleWrapper getAndPut(String className, MemoizeCache.ValueProvider<? super String, ? extends MethodHandleWrapper> valueProvider) { + final MemoizeCache<String, MethodHandleWrapper> cache = getCache(); final MethodHandleWrapper result = cache.getAndPut(className, valueProvider); final MethodHandleWrapper lhmh = latestHitMethodHandleWrapper; @@ -61,7 +63,7 @@ public class CacheableCallSite extends MutableCallSite { } public MethodHandleWrapper put(String name, MethodHandleWrapper mhw) { - return cache.put(name, mhw); + return getCache().put(name, mhw); } public long incrementFallbackCount() { @@ -87,4 +89,18 @@ public class CacheableCallSite extends MutableCallSite { public void setFallbackTarget(MethodHandle fallbackTarget) { this.fallbackTarget = fallbackTarget; } + + private MemoizeCache<String, MethodHandleWrapper> getCache() { + MemoizeCache<String, MethodHandleWrapper> cache; + SoftReference<MemoizeCache<String, MethodHandleWrapper>> ref = cacheSoftReference; + if (null == ref || null == (cache = ref.get())) { + synchronized (this) { + ref = cacheSoftReference; + if (null == ref || null == (cache = ref.get())) { + this.cacheSoftReference = new SoftReference<>(cache = new LRUCache<>(CACHE_SIZE)); + } + } + } + return cache; + } }
