You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by mr...@apache.org on 2010/05/17 06:36:47 UTC

svn commit: r944964 - /xerces/java/trunk/src/org/apache/xerces/impl/XMLEntityManager.java

Author: mrglavas
Date: Mon May 17 04:36:47 2010
New Revision: 944964

URL: http://svn.apache.org/viewvc?rev=944964&view=rev
Log:
Fixing a usually slow growing memory leak. When a UTF-8, UTF-16, UCS-2 or UCS-4 byte sequence crosses a buffer boundary we call the read() method on the RewindableInputStream. This was always buffering the value returned from the underlying InputStream in the data array even when it will never be read again. For a well behaved InputStream if this occurred on every buffer of a 2 GB document we'd grow the data array to over 1 MB. A pathological InputStream which always returns only a few bytes at time could have caused the memory to be burned much quicker.

Modified:
    xerces/java/trunk/src/org/apache/xerces/impl/XMLEntityManager.java

Modified: xerces/java/trunk/src/org/apache/xerces/impl/XMLEntityManager.java
URL: http://svn.apache.org/viewvc/xerces/java/trunk/src/org/apache/xerces/impl/XMLEntityManager.java?rev=944964&r1=944963&r2=944964&view=diff
==============================================================================
--- xerces/java/trunk/src/org/apache/xerces/impl/XMLEntityManager.java (original)
+++ xerces/java/trunk/src/org/apache/xerces/impl/XMLEntityManager.java Mon May 17 04:36:47 2010
@@ -1006,7 +1006,8 @@ public class XMLEntityManager
                 }
             }
             // wrap this stream in RewindableInputStream
-            stream = new RewindableInputStream(stream);
+            RewindableInputStream rewindableStream = new RewindableInputStream(stream);
+            stream = rewindableStream;
 
             // perform auto-detect of encoding if necessary
             if (encoding == null) {
@@ -1014,7 +1015,7 @@ public class XMLEntityManager
                 final byte[] b4 = new byte[4];
                 int count = 0;
                 for (; count<4; count++ ) {
-                    b4[count] = (byte)stream.read();
+                    b4[count] = (byte)rewindableStream.readAndBuffer();
                 }
                 if (count == 4) {
                     EncodingInfo info = getEncodingInfo(b4, count);
@@ -1052,7 +1053,7 @@ public class XMLEntityManager
                     final int[] b3 = new int[3];
                     int count = 0;
                     for (; count < 3; ++count) {
-                        b3[count] = stream.read();
+                        b3[count] = rewindableStream.readAndBuffer();
                         if (b3[count] == -1)
                             break;
                     }
@@ -1073,7 +1074,7 @@ public class XMLEntityManager
                     final int[] b4 = new int[4];
                     int count = 0;
                     for (; count < 4; ++count) {
-                        b4[count] = stream.read();
+                        b4[count] = rewindableStream.readAndBuffer();
                         if (b4[count] == -1)
                             break;
                     }
@@ -1112,7 +1113,7 @@ public class XMLEntityManager
                     final int[] b4 = new int[4];
                     int count = 0;
                     for (; count < 4; ++count) {
-                        b4[count] = stream.read();
+                        b4[count] = rewindableStream.readAndBuffer();
                         if (b4[count] == -1)
                             break;
                     }
@@ -1137,7 +1138,7 @@ public class XMLEntityManager
                     final int[] b4 = new int[4];
                     int count = 0;
                     for (; count < 4; ++count) {
-                        b4[count] = stream.read();
+                        b4[count] = rewindableStream.readAndBuffer();
                         if (b4[count] == -1)
                             break;
                     }
@@ -3105,21 +3106,14 @@ public class XMLEntityManager
         public void rewind() {
             fOffset = fStartOffset;
         }
-
-        public int read() throws IOException {
-            int b = 0;
-            if (fOffset < fLength) {
-                return fData[fOffset++] & 0xff;
-            }
-            if (fOffset == fEndOffset) {
-                return -1;
-            }
+        
+        public int readAndBuffer() throws IOException {
             if (fOffset == fData.length) {
                 byte[] newData = new byte[fOffset << 1];
                 System.arraycopy(fData, 0, newData, 0, fOffset);
                 fData = newData;
             }
-            b = fInputStream.read();
+            final int b = fInputStream.read();
             if (b == -1) {
                 fEndOffset = fOffset;
                 return -1;
@@ -3129,18 +3123,31 @@ public class XMLEntityManager
             return b & 0xff;
         }
 
+        public int read() throws IOException {
+            if (fOffset < fLength) {
+                return fData[fOffset++] & 0xff;
+            }
+            if (fOffset == fEndOffset) {
+                return -1;
+            }
+            if (fCurrentEntity.mayReadChunks) {
+                return fInputStream.read();
+            }
+            return readAndBuffer();
+        }
+
         public int read(byte[] b, int off, int len) throws IOException {
-            int bytesLeft = fLength - fOffset;
+            final int bytesLeft = fLength - fOffset;
             if (bytesLeft == 0) {
                 if (fOffset == fEndOffset) {
                     return -1;
                 }
                 // better get some more for the voracious reader...
-                if(fCurrentEntity.mayReadChunks) {
+                if (fCurrentEntity.mayReadChunks) {
                     return fInputStream.read(b, off, len);
                 }
-                int returnedVal = read();
-                if(returnedVal == -1) {
+                int returnedVal = readAndBuffer();
+                if (returnedVal == -1) {
                     fEndOffset = fOffset;
                     return -1;
                 }
@@ -3197,7 +3204,7 @@ public class XMLEntityManager
         }
 
         public int available() throws IOException {
-            int bytesLeft = fLength - fOffset;
+            final int bytesLeft = fLength - fOffset;
             if (bytesLeft == 0) {
                 if (fOffset == fEndOffset) {
                     return -1;



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xerces.apache.org
For additional commands, e-mail: commits-help@xerces.apache.org