You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2014/04/16 15:39:09 UTC

svn commit: r1587903 - in /uima/uimaj/trunk/uimaj-core/src: main/java/org/apache/uima/cas/impl/ test/java/org/apache/uima/cas/impl/

Author: schor
Date: Wed Apr 16 13:39:09 2014
New Revision: 1587903

URL: http://svn.apache.org/r1587903
Log:
[UIMA-3747] fix the WeakHashMap use to not hold strong refs in the value part to the type system of the key (which prevent it from being cleaned up).

Modified:
    uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java
    uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CasTypeSystemMapper.java
    uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java
    uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasTypeSystemMapperTst.java

Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java?rev=1587903&r1=1587902&r2=1587903&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java Wed Apr 16 13:39:09 2014
@@ -2709,7 +2709,7 @@ public class BinaryCasSerDes6 {
       //       previous delta deserialization)
       final TypeInfo srcTypeInfo = ts.getTypeInfo(tCode);
       final TypeInfo tgtTypeInfo = (isTypeMapping && isIncludedType) ? 
-          typeMapper.tsTgt.getTypeInfo(tgtTypeCode) : 
+          typeMapper.tsTgt.get().getTypeInfo(tgtTypeCode) : 
           srcTypeInfo;
       
       

Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CasTypeSystemMapper.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CasTypeSystemMapper.java?rev=1587903&r1=1587902&r2=1587903&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CasTypeSystemMapper.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CasTypeSystemMapper.java Wed Apr 16 13:39:09 2014
@@ -19,6 +19,7 @@
 
 package org.apache.uima.cas.impl;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
@@ -28,7 +29,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import org.apache.uima.cas.Type;
-import org.apache.uima.cas.TypeSystem;
 import org.apache.uima.resource.ResourceInitializationException;
 
 /**
@@ -64,7 +64,9 @@ public class CasTypeSystemMapper {
   private final static boolean[] BOOLEAN0 = new boolean[0];
   
   public final TypeSystemImpl tsSrc;  // source type system
-  public final TypeSystemImpl tsTgt;  // target type system
+  // weak ref to target type system, to allow that object to be gc'd
+  //   which in turn allows a weak map using these as keys to reclaim space
+  public final WeakReference<TypeSystemImpl> tsTgt;
   
   /** 
    * Map from source type codes to target type codes.  
@@ -106,7 +108,7 @@ public class CasTypeSystemMapper {
       throw new RuntimeException("Type Systems must be committed before calling this method");
     }
     this.tsSrc = tsSrc;
-    this.tsTgt = tsTgt;
+    this.tsTgt = new WeakReference<TypeSystemImpl>(tsTgt);
     
     int[] temptSrc2Tgt = null;
     int[] temptTgt2Src = null;

Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java?rev=1587903&r1=1587902&r2=1587903&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java Wed Apr 16 13:39:09 2014
@@ -36,17 +36,13 @@ import static org.apache.uima.cas.impl.S
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.NoSuchElementException;
 import java.util.Vector;
 import java.util.WeakHashMap;
-import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.uima.cas.CAS;
 import org.apache.uima.cas.Feature;
@@ -1605,7 +1601,7 @@ public class TypeSystemImpl implements T
    * The may itself is not synchronized, because all accesses to it are
    * from the synchronized getTypeSystemMapper method
    *********************************************************/
-  private final Map<TypeSystemImpl, CasTypeSystemMapper> typeSystemMappers = 
+  public final Map<TypeSystemImpl, CasTypeSystemMapper> typeSystemMappers = 
       new WeakHashMap<TypeSystemImpl, CasTypeSystemMapper>();
   
   synchronized CasTypeSystemMapper getTypeSystemMapper(TypeSystemImpl tgtTs) throws ResourceInitializationException {
@@ -1613,11 +1609,18 @@ public class TypeSystemImpl implements T
       return null;  // conventions for no type mapping
     }
     CasTypeSystemMapper m = typeSystemMappers.get(tgtTs);
+    
     if (null == m) {
       m = new CasTypeSystemMapper(this, tgtTs);
       typeSystemMappers.put(tgtTs, m);
     }
-    return (m.isEqual()) ? null : m;
+    
+    if (m.isEqual()) { // if the mapper is for this type system
+      typeSystemMappers.put(tgtTs,  null);
+      return null;
+    }
+    
+    return m;
   }
   
 }

Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasTypeSystemMapperTst.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasTypeSystemMapperTst.java?rev=1587903&r1=1587902&r2=1587903&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasTypeSystemMapperTst.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasTypeSystemMapperTst.java Wed Apr 16 13:39:09 2014
@@ -18,6 +18,8 @@
  */
 package org.apache.uima.cas.impl;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.util.BitSet;
 
 import junit.framework.TestCase;
@@ -31,6 +33,8 @@ import org.apache.uima.cas.admin.TypeSys
 import org.apache.uima.cas.test.AnnotatorInitializer;
 import org.apache.uima.cas.test.CASInitializer;
 import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.util.CasCreationUtils;
 
 public class CasTypeSystemMapperTst extends TestCase {
   
@@ -41,6 +45,44 @@ public class CasTypeSystemMapperTst exte
   protected void tearDown() throws Exception {
     super.tearDown();
   }
+  
+   // to run this test, change the visibility in TypeSystemImpl of typeSystemMappers to public
+//  public void testCasReuseWithDifferentTypeSystems() throws Exception {
+//    // Create a CAS
+//    CAS cas = CasCreationUtils.createCas((TypeSystemDescription) null, null, null);
+//    cas.setDocumentLanguage("latin");
+//    cas.setDocumentText("test");
+//
+//    // Serialize it
+//    ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+//    Serialization.serializeWithCompression(cas, baos, cas.getTypeSystem());
+//
+//    // Create a new CAS
+//    long min = Long.MAX_VALUE;
+//    long max = 0;
+//    CAS cas2 = CasCreationUtils.createCas((TypeSystemDescription) null, null, null);
+//    for (int i = 0; i < 100000; i++) {
+//      // Simulate us reinitializing the CAS with a new type system.
+//      TypeSystemImpl tgt = new TypeSystemImpl();
+//      for (int t = 0; t < 1000; t++) {
+//        tgt.addType("random" + t, tgt.getTopType());
+//      }
+//      tgt.commit();
+//
+//      // Deserialize into the new type system
+//      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+//      Serialization.deserializeCAS(cas2, bais, tgt, null);
+//
+//      long cur = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+//      max = Math.max(cur, max);
+//      min = Math.min(cur, min);
+//      if (i % 100 == 0) {
+//        System.out.printf("Cached: %d   Max: %d   Room left: %d   %n",
+//            ((TypeSystemImpl) cas2.getTypeSystem()).typeSystemMappers.size(), max, Runtime.getRuntime().maxMemory()
+//                - max);
+//      }
+//    }
+//  }
 
   public void testCasTypeSystemMapperFull() throws ResourceInitializationException {
     TypeSystemImpl ts1 = createTs(3, 0x1ffff, 0x1ffff);