From: remm Date: Sun, 4 Jun 2006 15:01:39 +0000 (+0000) Subject: - With Comet support, it is necessary to optimize the amount of memory used by individual X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=64b7538bf56b0e40a0ca04eb31e6dbfc4438edfa;p=tomcat7.0 - With Comet support, it is necessary to optimize the amount of memory used by individual processors. This removes most of the buffers that are being used, without reducing performance in many cases. - Note: I'm not sure the algorithm in InternalAprInputBuffer.nextRequest, which is used when pipelining, is correct. It also could use free space in the buffer more efficiently when trimming it. git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@411576 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/coyote/http11/InternalAprInputBuffer.java b/java/org/apache/coyote/http11/InternalAprInputBuffer.java index f40429cf7..699e2f8c1 100644 --- a/java/org/apache/coyote/http11/InternalAprInputBuffer.java +++ b/java/org/apache/coyote/http11/InternalAprInputBuffer.java @@ -55,14 +55,12 @@ public class InternalAprInputBuffer implements InputBuffer { this.request = request; headers = request.getMimeHeaders(); - headerBuffer1 = new byte[headerBufferSize]; - headerBuffer2 = new byte[headerBufferSize]; - bodyBuffer = new byte[headerBufferSize]; - buf = headerBuffer1; - bbuf = ByteBuffer.allocateDirect(headerBufferSize); - - headerBuffer = new char[headerBufferSize]; - ascbuf = headerBuffer; + buf = new byte[headerBufferSize]; + if (headerBufferSize < (8 * 1024)) { + bbuf = ByteBuffer.allocateDirect(6 * 1500); + } else { + bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500); + } inputStreamInputBuffer = new SocketInputBuffer(); @@ -126,12 +124,6 @@ public class InternalAprInputBuffer implements InputBuffer { /** - * Pointer to the US-ASCII header buffer. - */ - protected char[] ascbuf; - - - /** * Last valid byte. */ protected int lastValid; @@ -144,27 +136,10 @@ public class InternalAprInputBuffer implements InputBuffer { /** - * HTTP header buffer no 1. - */ - protected byte[] headerBuffer1; - - - /** - * HTTP header buffer no 2. - */ - protected byte[] headerBuffer2; - - - /** - * HTTP body buffer. + * Pos of the end of the header in the buffer, which is also the + * start of the body. */ - protected byte[] bodyBuffer; - - - /** - * US-ASCII header buffer. - */ - protected char[] headerBuffer; + protected int end; /** @@ -313,7 +288,6 @@ public class InternalAprInputBuffer implements InputBuffer { request.recycle(); socket = 0; - buf = headerBuffer1; lastValid = 0; pos = 0; lastActiveFilter = -1; @@ -334,20 +308,19 @@ public class InternalAprInputBuffer implements InputBuffer { // Recycle Request object request.recycle(); - // Determine the header buffer used for next request - byte[] newHeaderBuf = null; - if (buf == headerBuffer1) { - newHeaderBuf = headerBuffer2; - } else { - newHeaderBuf = headerBuffer1; + //System.out.println("LV-pos: " + (lastValid - pos)); + // Copy leftover bytes to the beginning of the buffer + if (lastValid - pos > 0) { + int npos = 0; + int opos = pos; + while (lastValid - opos > opos - npos) { + System.arraycopy(buf, opos, buf, npos, opos - npos); + npos += pos; + opos += pos; + } + System.arraycopy(buf, opos, buf, npos, lastValid - opos); } - - // Copy leftover bytes from buf to newHeaderBuf - System.arraycopy(buf, pos, newHeaderBuf, 0, lastValid - pos); - - // Swap buffers - buf = newHeaderBuf; - + // Recycle filters for (int i = 0; i <= lastActiveFilter; i++) { activeFilters[i].recycle(); @@ -479,11 +452,9 @@ public class InternalAprInputBuffer implements InputBuffer { throw new EOFException(sm.getString("iib.eof.error")); } - ascbuf[pos] = (char) buf[pos]; - if (buf[pos] == Constants.SP) { space = true; - request.method().setChars(ascbuf, start, pos - start); + request.method().setBytes(buf, start, pos - start); } pos++; @@ -554,8 +525,6 @@ public class InternalAprInputBuffer implements InputBuffer { throw new EOFException(sm.getString("iib.eof.error")); } - ascbuf[pos] = (char) buf[pos]; - if (buf[pos] == Constants.CR) { end = pos; } else if (buf[pos] == Constants.LF) { @@ -569,7 +538,7 @@ public class InternalAprInputBuffer implements InputBuffer { } if ((end - start) > 0) { - request.protocol().setChars(ascbuf, start, end - start); + request.protocol().setBytes(buf, start, end - start); } else { request.protocol().setString(""); } @@ -589,6 +558,7 @@ public class InternalAprInputBuffer implements InputBuffer { } parsingHeader = false; + end = pos; } @@ -651,15 +621,13 @@ public class InternalAprInputBuffer implements InputBuffer { if (buf[pos] == Constants.COLON) { colon = true; - headerValue = headers.addValue(ascbuf, start, pos - start); + headerValue = headers.addValue(buf, start, pos - start); } chr = buf[pos]; if ((chr >= Constants.A) && (chr <= Constants.Z)) { buf[pos] = (byte) (chr - Constants.LC_OFFSET); } - ascbuf[pos] = (char) buf[pos]; - pos++; } @@ -793,8 +761,7 @@ public class InternalAprInputBuffer implements InputBuffer { } bbuf.clear(); - nRead = Socket.recvbb - (socket, 0, buf.length - lastValid); + nRead = Socket.recvbb(socket, 0, buf.length - lastValid); if (nRead > 0) { bbuf.limit(nRead); bbuf.get(buf, pos, nRead); @@ -809,16 +776,21 @@ public class InternalAprInputBuffer implements InputBuffer { } else { - buf = bodyBuffer; - pos = 0; - lastValid = 0; + if (buf.length - end < 4500) { + // In this case, the request header was really large, so we allocate a + // brand new one; the old one will get GCed when subsequent requests + // clear all references + buf = new byte[buf.length]; + end = 0; + } + pos = end; + lastValid = pos; bbuf.clear(); - nRead = Socket.recvbb - (socket, 0, buf.length); + nRead = Socket.recvbb(socket, 0, buf.length - lastValid); if (nRead > 0) { bbuf.limit(nRead); - bbuf.get(buf, 0, nRead); - lastValid = nRead; + bbuf.get(buf, pos, nRead); + lastValid = pos + nRead; } else { throw new IOException(sm.getString("iib.failedread")); } diff --git a/java/org/apache/coyote/http11/InternalAprOutputBuffer.java b/java/org/apache/coyote/http11/InternalAprOutputBuffer.java index 5f737388c..e153dd909 100644 --- a/java/org/apache/coyote/http11/InternalAprOutputBuffer.java +++ b/java/org/apache/coyote/http11/InternalAprOutputBuffer.java @@ -62,10 +62,12 @@ public class InternalAprOutputBuffer this.response = response; headers = response.getMimeHeaders(); - headerBuffer = new byte[headerBufferSize]; - buf = headerBuffer; - - bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500); + buf = new byte[headerBufferSize]; + if (headerBufferSize < (8 * 1024)) { + bbuf = ByteBuffer.allocateDirect(6 * 1500); + } else { + bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500); + } outputStreamOutputBuffer = new SocketOutputBuffer(); @@ -120,7 +122,7 @@ public class InternalAprOutputBuffer /** - * Pointer to the current read buffer. + * Pointer to the current write buffer. */ protected byte[] buf; @@ -132,12 +134,6 @@ public class InternalAprOutputBuffer /** - * HTTP header buffer. - */ - protected byte[] headerBuffer; - - - /** * Underlying socket. */ protected long socket; @@ -316,7 +312,6 @@ public class InternalAprOutputBuffer bbuf.clear(); socket = 0; - buf = headerBuffer; pos = 0; lastActiveFilter = -1; committed = false; @@ -336,9 +331,6 @@ public class InternalAprOutputBuffer // Recycle Request object response.recycle(); - // Determine the header buffer used for next request - buf = headerBuffer; - // Recycle filters for (int i = 0; i <= lastActiveFilter; i++) { activeFilters[i].recycle();