Solved

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

Posted on 2004-04-27
15
1,428 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

 
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 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

SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

Question has a verified solution.

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

Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

717 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