Author: markt Date: Wed Mar 5 13:41:58 2014 New Revision: 1574484 URL: http://svn.apache.org/r1574484 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56213 Reduce GC when NIO connector is under load. Results in a small performance improvement. KeyReferences and finalizer references were accounting for 30%+ of the heap during my load tests before this patch.
Modified: tomcat/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1388890 Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java?rev=1574484&r1=1574483&r2=1574484&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/NioBlockingSelector.java Wed Mar 5 13:41:58 2014 @@ -26,6 +26,7 @@ import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; +import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -42,6 +43,9 @@ public class NioBlockingSelector { private static int threadCounter = 0; + private Queue<KeyReference> keyReferenceQueue = + new ConcurrentLinkedQueue<KeyReference>(); + protected Selector sharedSelector; protected BlockPoller poller; @@ -82,7 +86,10 @@ public class NioBlockingSelector { throws IOException { SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector()); if ( key == null ) throw new IOException("Key no longer registered"); - KeyReference reference = new KeyReference(); + KeyReference reference = keyReferenceQueue.poll(); + if (reference == null) { + reference = new KeyReference(); + } KeyAttachment att = (KeyAttachment) key.attachment(); int written = 0; boolean timedout = false; @@ -131,6 +138,7 @@ public class NioBlockingSelector { poller.cancelKey(reference.key); } reference.key = null; + keyReferenceQueue.add(reference); } return written; } @@ -150,7 +158,10 @@ public class NioBlockingSelector { public int read(ByteBuffer buf, NioChannel socket, long readTimeout) throws IOException { SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector()); if ( key == null ) throw new IOException("Key no longer registered"); - KeyReference reference = new KeyReference(); + KeyReference reference = keyReferenceQueue.poll(); + if (reference == null) { + reference = new KeyReference(); + } KeyAttachment att = (KeyAttachment) key.attachment(); int read = 0; boolean timedout = false; @@ -195,6 +206,7 @@ public class NioBlockingSelector { poller.cancelKey(reference.key); } reference.key = null; + keyReferenceQueue.add(reference); } return read; } Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1574484&r1=1574483&r2=1574484&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Mar 5 13:41:58 2014 @@ -78,6 +78,10 @@ NIO connector and a request is sent using more than one AJP message. Patch provided by Amund Elstad. (markt) </fix> + <fix> + <bug>56213</bug>: Reduce garbage collection when the NIO connector is + under heavy load. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org