|
Sponsored Links
Resources
Enterprise Java Research Library
Get Java white papers, product information, case studies and webcasts
|
Performance and scalability
Performance and scalability
Performance and scalability
|
Messages: 3
Messages: 3
Messages: 3
Printer friendly
Printer friendly
Printer friendly
Post reply
Post reply
Post reply
XML
XML
XML
|
 |
how to use java nio.channel with ObjectInputStream?
We are trying to port a current system from JDK 1.3 to JDK 1.4 using java nio.
I want to use java.nio.SocketChannel for asynchronous IO, order to reduce the number of threads bound to a Socket object and reading request from it in the past. The asynchronous IO is exactly what I want.
But our system is using ObjectInputStream and ObjectOutputStream now. As a SocketChannel only support read/write using ByteBuffer. So I would like to hear others suggestion here.
|
|
Message #96594
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
how to use java nio.channel with ObjectInputStream?
After literally years of experimenting, I've come to the conclusion that ObjectOutputStream and it's input sister are evil and should be eradicated from the planet.
Barring that, and since sometimes you do need to serialize an object, what I do is create an ObjectOutputStream backed by a ByteArrayOutputStream, writeObject(), grab the buffer, then use that for your input into a ByteBuffer.
If you want better performance, you can also very easily create something like a ByteBufferOutputStream() by extending OutputStream, with your ByteBufferOutputStream backed by a direct ByteBuffer. If you synchronize use of the BBOS properly, you can even reuse and resize the underlying ByteBuffer as necessary and avoid unnecessary buffer creations.
You can also use:
Channels.newInputStream (ReadableByteChannel)
Channels.newOutputStream (WritableByteChannel)
(there are also Streams-to-buffers static methods as well). I rolled my own to have better control, but it might be easier to use the above.
As an FYI, be careful if you're using Selectors and pre-Java 1.4 Stream code. When you pop out of a Select your Channel is in non-blocking mode. You'll need to either temporarily set it back to blocking (and then re-non-block it when adding it back to the Selector) or go fully non-blocking, which involves holding onto your ByteBuffer, reading/writing what you can, and re-injecting back into the Selector for read/write events and being sure to re-use the original Buffer when reading/write again (until you've got the data you need).
As a side note, since ObjectOutputStream buffers everything prior to 1.4, you have to flush it after each use, and I've found the flushing is an enormous CPU hog on the receiving end for some reason. It's actually to create a new ObjectOutputStream each time you're sending an object and then throw it away then to re-use an existing one.
-Mike
|
|
Message #96672
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
how to use java nio.channel with ObjectInputStream?
I would extend ByteArrayOutputStream to get access to the protected fields buf and count, so that you don't have to call toByteArray() (which stupidly clone the array, talk about memory waste).
Then I would do as said before, wrap this baos with oos, and write the assembled byte[] in your bytebuffer.
Client impl is trivial, bytearrayinputstream, although you could also extend to get access to protected fields, and exploit the "mark" & "reset" to rewind after filling the byte[] from the byte buffer.)
All solutions involve a "bytebuffer" pump.
Note: try externalizable instead of serializable, it requires you to code the persistence of fields, but it is much faster than default serialization which involves the native jvm code for reflection on fields. You may also find that you want your own protocol stack at some point, given that you are about to write bytes and not objects. In that perspective, serialization is all-or-nothing for me.
|
|
Message #96673
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
how to use java nio.channel with ObjectInputStream?
\Quartz Quartz\
I would extend ByteArrayOutputStream to get access to the protected fields buf and count, so that you don't have to call toByteArray() (which stupidly clone the array, talk about memory waste).
Then I would do as said before, wrap this baos with oos, and write the assembled byte[] in your bytebuffer.
Client impl is trivial, bytearrayinputstream, although you could also extend to get access to protected fields, and exploit the "mark" & "reset" to rewind after filling the byte[] from the byte buffer.)
\Quartz Quartz\
Yep, this is effectively what I do (except that I chose to subclass InputStream/OutputStream and use byte buffers under the covers). And I agree on the ByteArrayOutputStream toByteArray() call - it's silly that it clones the array every time, this wastes memory _and_ is slow.
\Quartz Quartz\
Note: try externalizable instead of serializable, it requires you to code the persistence of fields, but it is much faster than default serialization which involves the native jvm code for reflection on fields. You may also find that you want your own protocol stack at some point, given that you are about to write bytes and not objects. In that perspective, serialization is all-or-nothing for me.
\Quartz Quartz\
I think it's an excellent idea to write a little-protocol no matter what. It insulates you from a number of problems, and can make your connection survive things like ClassNotFoundExceptions. What I typically do is write a protocol somewhat like this for simple serialization:
<magic number> [integer]
<msg length> [integer]
<bytes> [Serialized object]
The <magic number> identifies the protocol, so if someone connects with the wrong kind of client you can reject it (you can also then support multiple protocols, and allow different versions of clients to connect to your server even if you need to make a protocol change). <msg_length> is the length of the following byte array, the byte array is the result of calling writeObject() on an ObjectOutputStream backed by a ByteArrayOutputStream or a custom sub-class which uses NIO buffers instead.
Externalizable is also a good idea if you control the classes - it is lots faster.
-Mike
|
|
 |
Hot threads
Hot threads
Hot threads
|
More hot threads
More hot threads
More hot threads
|
 |
Brian Goetz continues to lift the lid and peak into the inner workings of Java in Java Urban Performance Legends. In this article he exposes the fallacy behind some of the more common performance myths found in the annals of the JVM.
(93 comments,
last posted
February 06, 2009)
Bruce Tate, author of Better, Faster Lighter Java and Bitter EJB has come out with a new book called Beyond Java. Bruce has an epiphany about the future of software development. Does it include Java?
(770 comments,
last posted
September 23, 2009)
Looks like today AJAX concept have several interpretations. We can distinguish different approaches of AJAX integration. Can they co-exist within the same application? Can we talk about layered AJAX integration?
(68 comments,
last posted
May 08, 2008)
Artima has published a short article describing the Design-Time API for JavaBeans, which was recently approved as JSR 273. This API promises to bring VB-like ease to Java development, but may face a cultural bias among Java developers who tend to think more in terms of class libraries than components.
(225 comments,
last posted
November 19, 2009)
There is plenty of speculation today regarding a potential buyout of Sun Microsystems by Scott McNealy and Silver Lake Partners. How would privatization of Sun affect Java?
(16 comments,
last posted
May 15, 2009)
More hot threads »
|
|