You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-commits@lucene.apache.org by yo...@apache.org on 2010/03/06 23:49:24 UTC

svn commit: r919871 - in /lucene/solr/trunk: CHANGES.txt src/common/org/apache/solr/common/util/ConcurrentLRUCache.java src/java/org/apache/solr/search/FastLRUCache.java

Author: yonik
Date: Sat Mar  6 22:49:24 2010
New Revision: 919871

URL: http://svn.apache.org/viewvc?rev=919871&view=rev
Log:
SOLR-1798: fix FastLRUCache stats memory leak

Modified:
    lucene/solr/trunk/CHANGES.txt
    lucene/solr/trunk/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java
    lucene/solr/trunk/src/java/org/apache/solr/search/FastLRUCache.java

Modified: lucene/solr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/CHANGES.txt?rev=919871&r1=919870&r2=919871&view=diff
==============================================================================
--- lucene/solr/trunk/CHANGES.txt (original)
+++ lucene/solr/trunk/CHANGES.txt Sat Mar  6 22:49:24 2010
@@ -192,6 +192,9 @@
 * SOLR-1777: fieldTypes with sortMissingLast=true or sortMissingFirst=true can
   result in incorrectly sorted results.  (yonik)
 
+* SOLR-1798: Small memory leak (~100 bytes) in fastLRUCache for every
+  commit. (yonik)
+
 
 Other Changes
 ----------------------

Modified: lucene/solr/trunk/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java?rev=919871&r1=919870&r2=919871&view=diff
==============================================================================
--- lucene/solr/trunk/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java (original)
+++ lucene/solr/trunk/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java Sat Mar  6 22:49:24 2010
@@ -384,7 +384,7 @@
     CacheEntry<K,V> o = map.remove(key);
     if (o == null) return;
     stats.size.decrementAndGet();
-    stats.evictionCounter++;
+    stats.evictionCounter.incrementAndGet();
     if(evictionListener != null) evictionListener.evictedEntry(o.key,o.value);
   }
 
@@ -518,7 +518,7 @@
             nonLivePutCounter = new AtomicLong(0),
             missCounter = new AtomicLong();
     private final AtomicInteger size = new AtomicInteger();
-    private long evictionCounter = 0;
+    private AtomicLong evictionCounter = new AtomicLong();
 
     public long getCumulativeLookups() {
       return (accessCounter.get() - putCounter.get() - nonLivePutCounter.get()) + missCounter.get();
@@ -533,7 +533,7 @@
     }
 
     public long getCumulativeEvictions() {
-      return evictionCounter;
+      return evictionCounter.get();
     }
 
     public int getCurrentSize() {
@@ -547,6 +547,15 @@
     public long getCumulativeMisses() {
       return missCounter.get();
     }
+
+    public void add(Stats other) {
+      accessCounter.addAndGet(other.accessCounter.get());
+      putCounter.addAndGet(other.putCounter.get());
+      nonLivePutCounter.addAndGet(other.nonLivePutCounter.get());
+      missCounter.addAndGet(other.missCounter.get());
+      evictionCounter.addAndGet(other.evictionCounter.get());
+      size.set(Math.max(size.get(), other.size.get()));
+    }
   }
 
   public static interface EvictionListener<K,V>{

Modified: lucene/solr/trunk/src/java/org/apache/solr/search/FastLRUCache.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/search/FastLRUCache.java?rev=919871&r1=919870&r2=919871&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/search/FastLRUCache.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/search/FastLRUCache.java Sat Mar  6 22:49:24 2010
@@ -45,7 +45,8 @@
  */
 public class FastLRUCache<K,V> implements SolrCache<K,V> {
 
-  private List<ConcurrentLRUCache.Stats> cumulativeStats;
+  // contains the statistics objects for all open caches of the same type
+  private List<ConcurrentLRUCache.Stats> statsList;
 
   private long warmupTime = 0;
 
@@ -104,16 +105,18 @@
     cache = new ConcurrentLRUCache<K,V>(limit, minLimit, acceptableLimit, initialSize, newThread, false, null);
     cache.setAlive(false);
 
-    if (persistence == null) {
+    statsList = (List<ConcurrentLRUCache.Stats>) persistence;
+    if (statsList == null) {
       // must be the first time a cache of this type is being created
       // Use a CopyOnWriteArrayList since puts are very rare and iteration may be a frequent operation
       // because it is used in getStatistics()
-      persistence = new CopyOnWriteArrayList<ConcurrentLRUCache.Stats>();
-    }
+      statsList = new CopyOnWriteArrayList<ConcurrentLRUCache.Stats>();
 
-    cumulativeStats = (List<ConcurrentLRUCache.Stats>) persistence;
-    cumulativeStats.add(cache.getStats());
-    return cumulativeStats;
+      // the first entry will be for cumulative stats of caches that have been closed.
+      statsList.add(new ConcurrentLRUCache.Stats());
+    }
+    statsList.add(cache.getStats());
+    return statsList;
   }
 
   public String name() {
@@ -131,7 +134,6 @@
 
   public V get(K key) {
     return cache.get(key);
-
   }
 
   public void clear() {
@@ -177,6 +179,9 @@
 
 
   public void close() {
+    // add the stats to the cumulative stats object (the first in the statsList)
+    statsList.get(0).add(cache.getStats());
+    statsList.remove(cache.getStats());
     cache.destroy();
   }
 
@@ -243,7 +248,7 @@
     long cevictions = 0;
 
     // NOTE: It is safe to iterate on a CopyOnWriteArrayList
-    for (ConcurrentLRUCache.Stats statistiscs : cumulativeStats) {
+    for (ConcurrentLRUCache.Stats statistiscs : statsList) {
       clookups += statistiscs.getCumulativeLookups();
       chits += statistiscs.getCumulativeHits();
       cinserts += statistiscs.getCumulativePuts();