Index: java/engine/org/apache/derby/impl/store/access/RAMTransaction.java =================================================================== --- java/engine/org/apache/derby/impl/store/access/RAMTransaction.java (revision 466084) +++ java/engine/org/apache/derby/impl/store/access/RAMTransaction.java (working copy) @@ -21,12 +21,14 @@ package org.apache.derby.impl.store.access; +import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.Properties; import java.util.Vector; import org.apache.derby.iapi.reference.SQLState; +import org.apache.derby.iapi.util.ReuseFactory; import org.apache.derby.iapi.services.context.ContextManager; @@ -120,6 +122,11 @@ private Vector sorts; private Vector sortControllers; + /** List of sort identifiers (represented as Integer objects) + * which can be reused. Since sort identifiers are used as array indexes, + * we need to reuse them to avoid leaking memory (DERBY-912). */ + private ArrayList freeSortIds; + /** Where to look for temporary conglomerates. **/ @@ -163,6 +170,7 @@ conglomerateControllers = new Vector(); sorts = null; // allocated on demand. + freeSortIds = null; // allocated on demand. sortControllers = null; // allocated on demand if (parent_tran != null) @@ -314,6 +322,7 @@ sort.drop(this); } sorts.removeAllElements(); + freeSortIds.clear(); } } } @@ -1717,11 +1726,23 @@ estimatedRowSize); // Add the sort to the sorts vector - if (sorts == null) + if (sorts == null) { sorts = new Vector(); - long sortid = sorts.size(); - sorts.addElement(sort); + freeSortIds = new ArrayList(); + } + int sortid; + if (freeSortIds.isEmpty()) { + // no free identifiers, add sort at the end + sortid = sorts.size(); + sorts.addElement(sort); + } else { + // reuse a sort identifier + sortid = ((Integer) freeSortIds.remove(freeSortIds.size() - 1)) + .intValue(); + sorts.setElementAt(sort, sortid); + } + return sortid; } @@ -1748,6 +1769,7 @@ { sort.drop(this); sorts.setElementAt(null, (int) sortid); + freeSortIds.add(ReuseFactory.getInteger((int) sortid)); } }