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 2015/11/02 02:29:56 UTC
svn commit: r1711872 -
/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/JCasRegistry.java
Author: schor
Date: Mon Nov 2 01:29:56 2015
New Revision: 1711872
URL: http://svn.apache.org/viewvc?rev=1711872&view=rev
Log:
[UIMA-4666] update registry code to be more efficient
Modified:
uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/JCasRegistry.java
Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/JCasRegistry.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/JCasRegistry.java?rev=1711872&r1=1711871&r2=1711872&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/JCasRegistry.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/JCasRegistry.java Mon Nov 2 01:29:56 2015
@@ -18,6 +18,8 @@
*/
package org.apache.uima.jcas;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import org.apache.uima.jcas.cas.TOP;
@@ -26,20 +28,53 @@ import org.apache.uima.jcas.cas.TOP;
* Maintains a registry of JCas cover classes that have been loaded. Methods on this
* class are called from JCas cover classes (that is, classes generated by JCasGen).
* They are not intended to be called directly from user-written code.
+ *
+ * There are two kinds of JCasr classes: built-in and other.
+ * JCas "other" classes may have multiple versions for the same named class generated and loaded
+ * under different class loaders;
+ *
+ * This supports the use cases of
+ * - different type systems being used, either
+ * -- sequentially by a single instance of UIMA or
+ * -- multiple instances of pipelines running in one JVM each with different type systems
+ *
+ * To avoid memory leaks, weak refs are used.
*/
public class JCasRegistry {
- private static ArrayList<Class<? extends TOP>> loadedJCasClasses = new ArrayList<>();
+
+ private static class WeakRefInt<T> extends WeakReference<T> {
+ int index;
+
+ WeakRefInt(T item, ReferenceQueue<T> q, int index) {
+ super(item, q);
+ this.index = index;
+ }
+ }
+
+ final private static ArrayList<WeakRefInt<Class<? extends TOP>>> loadedJCasClasses = new ArrayList<>();
+ final private static ReferenceQueue<Class<? extends TOP>> releasedQueue = new ReferenceQueue<>();
/**
* Registers a JCas cover class with this registry. The registry will assign
* it a unique index, which is then used by the cover-class to identify itself
* to the JCas implementation.
+ *
+ * Before adding the class to the array list, see if there are any "free" slots in the array list
* @param aJCasCoverClass the class to register
* @return the unique index value for this class.
*/
public static synchronized int register(Class<? extends TOP> aJCasCoverClass) {
- loadedJCasClasses.add(aJCasCoverClass);
- return loadedJCasClasses.size() - 1;
+ WeakRefInt<Class<? extends TOP>> releasedWeakRef = (WeakRefInt<Class<? extends TOP>>) releasedQueue.poll();
+
+ if (releasedWeakRef != null) {
+ int i = ((WeakRefInt<Class<? extends TOP>>)releasedWeakRef).index;
+ loadedJCasClasses.set(i, new WeakRefInt<Class<? extends TOP>>(aJCasCoverClass, releasedQueue, i));
+ return i;
+ }
+
+ int i = loadedJCasClasses.size();
+ loadedJCasClasses.add(new WeakRefInt<Class<? extends TOP>>(aJCasCoverClass, releasedQueue, i));
+ return i;
}
/**
@@ -78,7 +113,7 @@ public class JCasRegistry {
*/
public static synchronized Class<? extends TOP> getClassForIndex(int aIndex) {
if (aIndex >= 0 && aIndex < loadedJCasClasses.size())
- return loadedJCasClasses.get(aIndex);
+ return loadedJCasClasses.get(aIndex).get();
else
return null;
}