From the thread: http://www.JavaGaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=Networking;action=display;num=1052749856;start=45#45
…
Arrgh. I think I’ve just encountered the same problem in a different server. I’ve got a semi-production server (which for a month has been running a game OK) which has been fine with three Selectors. Performance has been good.
I just added a new processing module, and suddenly the performance on the Write Selector has gone through the floor and is busily tunnelling it’s way to Australia.
First response takes 3 seconds (!) to send (it’s only 63k, on a LAN!). If the request is repeated, the response takes 60 seconds (!) sending almost exactly the same data. If you try a third time, linux crashes - or sometimes, you get a lot of disk thrasing, linux kills the JVM process, doesn’t crash [phew!] and you are left with 12 zombie JVM processes sharing 200 Mb of RAM - EACH process has to be force killed (signal 9) individually; note: normally in linux, killing one JVM process kills the lot, because the other processes are just the different threads within the JVM.
Normally, typical responses of the order of a few kb are transferred at LAN speeds (multiple Mbits, i.e. you’d expect perhaps 10 milliseconds for the transfer, not multiple seconds).
Profiling shows nothing - no CPU hogs, no memory hogs. This seems therfore to be a problem with the JDK 1.4.2 implementation of Selector’s and/or ByteBuffer’s (this is the only way I can think of that RAM usage and/or CPU usage are taking place but are invisible within the JVM?).
Interestingly, none of my base code has changed - all my processing is abstracted away from the Selector’s (I just add a new module that returns String’s to the lower-layer which sends them etc), so the only thing that is different between when I had no problems and now is the length of the response and the actual bytes involved.
Interesting points:
- My SO_SENDBUF is currently approx 25k. Previous responses have typically been 10k-20k (although I have NOT measured this for all of them); it is possible that this is the first time I’m going over the size of the default send buffer.
- I’ve been making excessive use of the convenience method in nio.charset:
ByteBuffer bb = ((Charset) ch).encode( String );
…unfortunately, the nio team didn’t document what kind of BB that code generates (direct, indirect, etc?) and any performance considerations. This is the one of the few “unknown quantity”'s in my code, so I’m treating it as potentially suspicious.
Could you try experimenting with limiting your requests to slightly less than the SO_SENDBUF? (have a look at Socket.getSendBufferSize() ). You can also change the size of SO_SENDBUF, but that may have further unpredictable effects, so I would suggest that you first of all just limit the amount of data you’re sending…
If that has no effect, then are you making similar usage of Charset’s?