Hi all, I am currently stress testing my application that uses MINA. In my stress test I am quite satisfied with the TPS handled by the application, but still i think there is room for improvement. I am using mina 2.0.7 and i monitored during the stress test using the VisualVM. CPU sampler shows huge amount spend in the DefaultWriteRequestQueue.size method.
org.apache.mina.core.session.DefaultIoSessionDataStructureFactory$DefaultWriteRequestQueue.size() 70.299576 2138327 ms (70.3%) 2138327 ms >From the thread dump I could see that most threads were spending most of the time in the following stack trace: java.lang.Thread.State: RUNNABLE at java.util.concurrent.ConcurrentLinkedQueue.size(ConcurrentLinkedQueue.java:449) at org.apache.mina.core.session.DefaultIoSessionDataStructureFactory$DefaultWriteRequestQueue.size(DefaultIoSessionDataStructureFactory.java:232) at org.apache.mina.core.session.AbstractIoSession$CloseAwareWriteQueue.size(AbstractIoSession.java:1388) at org.apache.mina.core.filterchain.DefaultIoFilterChain$HeadFilter.filterWrite(DefaultIoFilterChain.java:600) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callPreviousFilterWrite(DefaultIoFilterChain.java:482) at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1400(DefaultIoFilterChain.java:47) at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.filterWrite(DefaultIoFilterChain.java:775) at org.apache.mina.core.filterchain.IoFilterAdapter.filterWrite(IoFilterAdapter.java:123) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callPreviousFilterWrite(DefaultIoFilterChain.java:482) at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1400(DefaultIoFilterChain.java:47) at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.filterWrite(DefaultIoFilterChain.java:775) at org.apache.mina.filter.codec.ProtocolCodecFilter.filterWrite(ProtocolCodecFilter.java:331) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callPreviousFilterWrite(DefaultIoFilterChain.java:482) at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1400(DefaultIoFilterChain.java:47) at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.filterWrite(DefaultIoFilterChain.java:775) at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.filterWrite(DefaultIoFilterChain.java:705) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callPreviousFilterWrite(DefaultIoFilterChain.java:482) at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireFilterWrite(DefaultIoFilterChain.java:475) at org.apache.mina.core.session.AbstractIoSession.write(AbstractIoSession.java:494) at org.apache.mina.core.session.AbstractIoSession.write(AbstractIoSession.java:439) As it is states in the javadoc http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html ConcurrentLinkedQueue#size() method is *NOT* a constant-time operation. Actually it seems quite costly as it tries to determine the first element in a for(;;) loop ( http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/AbstractCollection.java#AbstractCollection.size%28%29 ). Since the stress test adds in the queue constantly i think that there, the problems begins. I found a commit related to the following code in DefaultIoChain ( http://mail-archives.apache.org/mod_mbox/mina-commits/201209.mbox/%3c20120928145021.1d32c2388...@eris.apache.org%3E ) - s.getWriteRequestQueue().offer(s, writeRequest); + WriteRequestQueue writeRequestQueue = s.getWriteRequestQueue(); + if (!s.isWriteSuspended()) { - s.getProcessor().flush(s); + if (writeRequestQueue.size() == 0) { + // We can write directly the message + s.getProcessor().write(s, writeRequest); + } else { + s.getWriteRequestQueue().offer(s, writeRequest); + s.getProcessor().flush(s); + } + } else { + s.getWriteRequestQueue().offer(s, writeRequest); } } Is this improvement really necessary? The "if (writeRequestQueue.size() == 0)" statement seems to be causing huge load for me. Thank you in advance! Best regards, Alex