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 2022/01/08 13:26:15 UTC

[groovy] branch master updated: GROOVY-10232: Massive increase in memory usage due to CacheableCallSite

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 66bb24a  GROOVY-10232: Massive increase in memory usage due to CacheableCallSite
66bb24a is described below

commit 66bb24acabe6a7a700c3d09c8fa0bc6b236d535b
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jan 8 21:25:42 2022 +0800

    GROOVY-10232: Massive increase in memory usage due to CacheableCallSite
---
 .../groovy/vmplugin/v8/CacheableCallSite.java      | 28 +++++++++++++++++-----
 1 file changed, 22 insertions(+), 6 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..aaa7138 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java
@@ -19,12 +19,13 @@
 package org.codehaus.groovy.vmplugin.v8;
 
 import org.apache.groovy.util.SystemUtil;
-import org.codehaus.groovy.runtime.memoize.LRUCache;
 import org.codehaus.groovy.runtime.memoize.MemoizeCache;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodType;
 import java.lang.invoke.MutableCallSite;
+import java.util.LinkedHashMap;
+import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -33,19 +34,32 @@ import java.util.concurrent.atomic.AtomicLong;
  * @since 3.0.0
  */
 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 static final int CACHE_SIZE = SystemUtil.getIntegerSafe("groovy.indy.callsite.cache.size", 4);
+    private static final float LOAD_FACTOR = 0.75f;
+    private static final int INITIAL_CAPACITY = (int) Math.ceil(CACHE_SIZE / LOAD_FACTOR) + 1;
     private volatile MethodHandleWrapper latestHitMethodHandleWrapper = null;
-    private final AtomicLong fallbackCount = new AtomicLong(0);
+    private final AtomicLong fallbackCount = new AtomicLong();
     private MethodHandle defaultTarget;
     private MethodHandle fallbackTarget;
+    private final Map<String, MethodHandleWrapper> lruCache =
+            new LinkedHashMap<String, MethodHandleWrapper>(INITIAL_CAPACITY, LOAD_FACTOR, true) {
+                private static final long serialVersionUID = 7785958879964294463L;
+
+                @Override
+                protected boolean removeEldestEntry(Map.Entry eldest) {
+                    return size() > CACHE_SIZE;
+                }
+            };
 
     public CacheableCallSite(MethodType type) {
         super(type);
     }
 
     public MethodHandleWrapper getAndPut(String className, MemoizeCache.ValueProvider<? super String, ? extends MethodHandleWrapper> valueProvider) {
-        final MethodHandleWrapper result = cache.getAndPut(className, valueProvider);
+        final MethodHandleWrapper result;
+        synchronized (lruCache) {
+            result = lruCache.computeIfAbsent(className, valueProvider::provide);
+        }
         final MethodHandleWrapper lhmh = latestHitMethodHandleWrapper;
 
         if (lhmh == result) {
@@ -61,7 +75,9 @@ public class CacheableCallSite extends MutableCallSite {
     }
 
     public MethodHandleWrapper put(String name, MethodHandleWrapper mhw) {
-        return cache.put(name, mhw);
+        synchronized (lruCache) {
+            return lruCache.put(name, mhw);
+        }
     }
 
     public long incrementFallbackCount() {