Solved

ServerSocket.accept() and SocketInputStream.read() consuming lots of cpu

Posted on 2004-04-27
15
1,404 Views
Last Modified: 2007-12-19
      I am having performance problems with a server socket application. When I profile it I got the following strange result:

      java.net.SocketInputStream.socketRead0  55 s (49 %)  
      java.net.PlainSocketImpl.socketAccept  53 s     (46 %)
      and less than 5% for the rest of my code (~1200 java classes).

      I profile the application with only ONE connection and about 1Kbps of transmition between the server and the client.

      Why is this happening?  Is this a bug? Aren´t those functions supposed to do nothing if there are nothing to execute? The accept() function only do something useful ONE time!

       Below is the code for NetworkServer.run() that contains the accept() function:

          while(bInitialized)
          {
                try
                {
                      NetWorkServerClient client=null;
                      Socket clientSocket = socket.accept();
                      client = new NetWorkServerClient(this,clientSocket);
                      
                      if(iClientsLimit > 0 && clients.size() >= iClientsLimit)
                      {
                                      client.stopListening();
                            client = null;
                           
                            continue;
                      }
                      else
                      {
                            client.start();
                            clients.add(client);
                      }
               
                      manager.onConnect(client);
                }
                catch(InterruptedIOException e)
                {
      
                }
          }
      }

     and NetworkServerClient.run() that contains the read() function:
      while(bInitialized)
      {
            int iBytesFilled = 0;
          try
          {
                iBytesFilled = in.read(btInBuffer,0,NetWorkUtils.getMaxPacketSize());
               
                if (iBytesFilled == 0)
                      continue;
               
          }
          catch(Exception e)
          {
                logConn();
                break;
          }
          
          if(iBytesFilled>0)
          {
                byte []btData = new byte[iBytesFilled];
                for(int i=0; i<iBytesFilled; i++)
                      btData[i]=btInBuffer[i];

               
                try
                {      
                      decode(btData);
                }
                catch(Exception e)
                {
                  logConn();
                             break;
                }
          }
          else if(iBytesFilled == -1)
          {
            logConn();
                break;
          }
            
      }
      bStopped = true;

      try
      {
            notifyAll();
      }
      catch(Exception e)
      {
      }

      stopListening();
}

   Thanks for any help.
0
Comment
Question by:Binder
  • 5
  • 5
  • 3
  • +1
15 Comments
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 10935631
It means that of the time spent in your application executing code is spent the way described in the output. I.e. you probably ran your application for 2 minutes. Of that 2 minutes 55 seconds was spent blocking on input, and 53 seconds was spent waiting for a connection. Unless it is multi-threaded, in which case you probably ran the application for one minute.
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 10938201
You can try the JProfiler to see the Java performance:

http://www.javaperformancetuning.com/tools/jprofiler/index.shtml

http://www.ej-technologies.com/products/jprofiler/overview.html

Make sure you are closing all sockets, streams, files, etc after you are using them.
0
 
LVL 1

Author Comment

by:Binder
ID: 10938330
  I know what it means, the read is inside a thread, I am using JProfiler and I close everything. My question is: is this behavior acceptable? The most part of my applicattion is taken by read and accept methods? I am losing performance!  I think that there is something wrong here, this can´t be the standard behaviour or my code is completely wrong.
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 30

Expert Comment

by:Mayank S
ID: 10938552
>> is this behavior acceptable?

No.

>> The most part of my applicattion is taken by read and accept methods?

How long is your code? Can you post it?
0
 
LVL 1

Author Comment

by:Binder
ID: 10938689
  You mean the other classes? About 400.000 lines. No, i can´t post, sorry. But if the problem is read and accept (that are called ONLY on the code shown above) why do you want the other classes?
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 10939172
Increase the load on your server and see what the profiling results are, you should see an increase in time in your application code and less in the blocking calls. Have you profiled your test client?

 >> is this behavior acceptable?
>> No.
We don't know enough to make that determination yet
0
 
LVL 1

Author Comment

by:Binder
ID: 10939276
 I have already done this. With 100 connections the result is the same. The read and accept threads block the cpu in the same way that one connection does.
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 10940595
>> We don't know enough to make that determination yet

Well, but it is slow from a user's point of view, which makes it slightly unacceptable for him.
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 10940749
>>  I have already done this. With 100 connections the result is the same. The read and accept threads block the cpu in the same way that one connection does.
So it does behave the way it is supposed to (assuming that you mean that you get the same times distributed over 49%,46%,5%).
0
 
LVL 13

Accepted Solution

by:
Webstorm earned 500 total points
ID: 10941009
Hi Binder,

Which performance results do you get if you run the server and wait for 5 minutes before making a connection with a client ? and for 10 minutes ?
If you get about 5 and 10 minutes (300 & 1200 s) for accept(), then it means that with Jperform you get the delay before the accept() method returns which is not the cpu time used.
0
 
LVL 1

Author Comment

by:Binder
ID: 10943070
 Yes, you are correct. But how can I profile the application if it gives me delays instead of cpu time?
0
 
LVL 13

Expert Comment

by:Webstorm
ID: 10943629
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 10943708
>> But how can I profile the application if it gives me delays instead of cpu time?
One manual way of doing (not the best way) would be to have a running tally of how long time is spent blocking on the blocking calls and assume that no time is spent there at all.

Another way, more applicable to your case would be to ignore the time spent in the blocking state on accept(), and compare time spent in the client read() method minus the time spent in  java.net.SocketInputStream.socketRead0.
0
 
LVL 1

Author Comment

by:Binder
ID: 10943940
  Ok, thanks Webstorm.
0
 
LVL 14

Expert Comment

by:Tommy Braas
ID: 10944019
:-(
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
groupSum5 challenge 5 84
JList custom Cell Renderer refresh 15 56
hibernate example for saving data 19 37
runtime exception 2 27
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
This video teaches viewers about errors in exception handling.

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now