Thanks Mike! ----- Original Message ---- From: Mike Heath <[EMAIL PROTECTED]> To: [email protected] Sent: Wednesday, August 29, 2007 2:35:22 PM Subject: Re: efficient byte shuffling
Please see my comments in line. Rob Butler wrote: > Hello all, > > I've a few quick questions regarding byte buffers and recycling in > Mina. > > Let's say I've got two connections to a Mina server. I'm sending > messages consisting of a "header" and "body" and I want to move > messages these between the two connections. The header on the > incoming message will be stripped off and replaced with a new header > before the message is sent to the other connection. With fixed size > headers I'd normally use scatter gather operations to efficiently > "parse" these messages into the two parts. Is this still possible > with Mina? How would I do this? > > The key to building an efficient server is to minimize GC. To that > end, my initial though for passing messages between these two > connections is to simply take the byte buffer passed during > messageReceived and pass it to the other IoSession.write(..). But I > don't think this will work properly because of byte buffer recycling. > The incoming byte buffer could be "recycled" by mina before the > outgoing IoSession.write(..) happened. This would cause corruption > of the data. What is the best way to move bytes between two streams > without unnecessarily creating lots of short lived buffers or other > objects? A number of Mina users have reported better performance using heap buffers instead of direct buffers. See the section "ByteBuffer Pooling Has Been Removed, and a Heap Buffer is the Default Buffer Type" at http://mina.apache.org/changes-between-2x-and-1x.html as well as this entry from the FAQ http://mina.apache.org/faq.html#FAQ-Iget%7B%7BOutOfMemoryError%7D%7Dorresponsetimeoutandconnectionresetunderheavyload. > One of the benefits of NIO is moving bytes between streams "in the > kernel". I.E. you don't have to bring the data into "user space" to > copy it from one stream to another and this reduces kernel context > switches. How do I take advantage of this in Mina? Once data is put into a ByteBuffer, it is in user space. Direct buffers having nothing to do with user space vs. kernel space. With Java NIO, you can only take advantage of "zero copy" between streams if you use a FileChannel and use transferTo (write the contents of the file to another file or socket) or transferFrom (read data from another file or socket and write it to the file.) If there is a zero copy socket to socket available in Java, I am unaware of it. MINA 2 will include support for utilizing FileChannel.transferTo for efficiently writing file data to the remote host. > > Basically I'm looking for the most efficient way to move bytes from > one stream to another. These bytes will actually be "messages" with > a header and body. The header will be changed between reception and > transmission. I also need to perform some routing logic using the > header. If necessary for efficiency I could use a fixed size header, > but would prefer not to. If you turn off buffer pooling per the FAQ entry I mentioned above, you can just write the ByteBuffer from messageReceived to IoSession.write and it should work fine and still be very efficient. -Mike ____________________________________________________________________________________ Take the Internet to Go: Yahoo!Go puts the Internet in your pocket: mail, news, photos & more. http://mobile.yahoo.com/go?refer=1GNXIC
