667481 members! Sign up to stay informed.

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?

Posted by: Xun Zhang on September 23, 2003 DIGG
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?

Posted by: Mike Spille on September 23, 2003 in response to Message #96593
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?

Posted by: Quartz Quartz on September 24, 2003 in response to Message #96594
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?

Posted by: Mike Spille on September 24, 2003 in response to Message #96672
\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

Recent active threads Recent active threads Recent active threads More More More
IPhone App Development with JSF
Web as the Platform: Day 1 at the Ajax Experience
Need help for login page using java servlet
Stateful Webservice in java
SAP Asks Sun/Oracle to Let Java Be Free
Registration for TheServerSide Java Symposium Las Vegas now open
Use Sun SPOTs as your build canary
AspectJ In Action Published; Sample Chapters Posted on TSS
WSO2 goes all RESTy
Return to previous view after user action
More active threads »
Top posters of the weekTop posters of the weekTop posters of the week
This list contains the members who have made the most posts in all forums over the last 7 days:
  1. Dan Evans
  2. James Watson
  3. William Louth
  4. sara foster
  5. Chief Thrall
Hot threads Hot threads Hot threads More hot threads More hot threads More hot threads

Object pooling is now a serious performance loss

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)

Beyond Java

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)

Three forms of AJAX: solid, liquid and gas.

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)

Design-Time API Promises to make Java more like VB

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)

Will Sun be that target of a management buyout?

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 »

News | Blogs | Discussions | Tech talks | Patterns | Reviews | White Papers | Downloads | Articles | Media kit | About
Java Solutions
All Content Copyright ©2007 TheServerSide Privacy Policy      Powered by JIVE
Site Map