From: <wol...@us...> - 2008-07-23 09:34:21
|
Revision: 8054 http://exist.svn.sourceforge.net/exist/?rev=8054&view=rev Author: wolfgang_m Date: 2008-07-23 09:34:19 +0000 (Wed, 23 Jul 2008) Log Message: ----------- [bugfix] fixed memory leak: when validating a document, xerces can consume quite a lot of memory for temporary data structures. Unfortunately, those data structures are not cleared afterwards. Pooling the XML parser can thus cause a serious memory leak. To work around those issues, eXist now checks the size of the last document that was parsed. If the document was a small one, the XML parser is pooled. For larger documents, we throw the parser away. Port of rev8053. Revision Links: -------------- http://exist.svn.sourceforge.net/exist/?rev=8053&view=rev Modified Paths: -------------- branches/eXist-stable-1.2/src/org/exist/Indexer.java branches/eXist-stable-1.2/src/org/exist/collections/Collection.java Modified: branches/eXist-stable-1.2/src/org/exist/Indexer.java =================================================================== --- branches/eXist-stable-1.2/src/org/exist/Indexer.java 2008-07-23 09:17:41 UTC (rev 8053) +++ branches/eXist-stable-1.2/src/org/exist/Indexer.java 2008-07-23 09:34:19 UTC (rev 8054) @@ -107,6 +107,8 @@ protected boolean suppressWSmixed = false; + protected int docSize = 0; + /* used to record the number of children of an element during * validation phase. later, when storing the nodes, we already * know the child count and don't need to update the element @@ -119,8 +121,6 @@ // the current nodeFactoryInstanceCnt private int nodeFactoryInstanceCnt = 0; - - // reusable fields private TextImpl text = new TextImpl(); @@ -192,6 +192,7 @@ level = 0; currentPath.reset(); stack = new Stack(); + docSize = 0; nsMappings.clear(); indexListener = null; rootNode = null; @@ -211,7 +212,11 @@ public DocumentImpl getDocument() { return document; } - + + public int getDocSize() { + return docSize; + } + public void characters(char[] ch, int start, int length) { if (length <= 0) return; @@ -480,8 +485,9 @@ progress = new ProgressIndicator(currentLine, 100); document.setChildCount(0); elementCnt = 0; - } } + docSize = 0; + } public void startElement(String namespace, String name, String qname, Attributes attributes) throws SAXException { @@ -587,7 +593,6 @@ } document.appendChild(node); } - level++; String attrPrefix; @@ -643,6 +648,7 @@ } } } + ++docSize; } private void storeText() { Modified: branches/eXist-stable-1.2/src/org/exist/collections/Collection.java =================================================================== --- branches/eXist-stable-1.2/src/org/exist/collections/Collection.java 2008-07-23 09:17:41 UTC (rev 8053) +++ branches/eXist-stable-1.2/src/org/exist/collections/Collection.java 2008-07-23 09:34:19 UTC (rev 8054) @@ -93,11 +93,9 @@ public class Collection extends Observable implements Comparable, Cacheable { public static int LENGTH_COLLECTION_ID = 4; //sizeof int - - public Collection(){ - - } + public static final int POOL_PARSER_THRESHOLD = 500; + private final static int SHALLOW_SIZE = 550; private final static int DOCUMENT_SIZE = 450; @@ -147,6 +145,10 @@ /** is this a temporary collection? */ private boolean isTempCollection = false; + + public Collection(){ + + } public Collection(XmldbURI path) { setPath(path); @@ -907,7 +909,7 @@ } catch (IOException e) { throw new EXistException(e); } finally { - releaseReader(broker, reader); + releaseReader(broker, info, reader); } } }); @@ -942,7 +944,7 @@ } catch (IOException e) { throw new EXistException(e); } finally { - releaseReader(broker, reader); + releaseReader(broker, info, reader); } } }); @@ -1092,7 +1094,7 @@ } catch (IOException e) { throw new EXistException(e); } finally { - releaseReader(broker, reader); + releaseReader(broker, info, reader); } } }); @@ -1617,14 +1619,14 @@ // Get reader from readerpool. XMLReader reader= broker.getBrokerPool().getParserPool().borrowXMLReader(); - + // If Collection configuration exists (try to) get validation mode // and setup reader with this information. if( colconfig!=null ) { int mode=colconfig.getValidationMode(); XMLReaderObjectFactory.setReaderValidationMode(mode, reader); - } - + } + // Return configured reader. return reader; } @@ -1632,11 +1634,12 @@ /** * Reset validation mode of reader and return reader to reader pool. */ - private void releaseReader(DBBroker broker, XMLReader reader) { + private void releaseReader(DBBroker broker, IndexInfo info, XMLReader reader) { if(userReader != null){ return; } - + if (info.getIndexer().getDocSize() > POOL_PARSER_THRESHOLD) + return; // Get validation mode from static configuration Configuration config = broker.getConfiguration(); String optionValue = (String) config.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |