why does my Java console program take up so much CPU time?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • tekninja
    New Member
    • Aug 2007
    • 4

    why does my Java console program take up so much CPU time?

    I wrote a very simple instant messenger client but, unfortunately, since I am still a relatively new programmer I am not familiar with what causes a program to eat up so much CPU time. Currently at runtime my program takes up 11mb in memory and 90-100% cpu usage!!

    Without posting all the code, what factors contribute to cpu usage? I am not really sure what information would help others troubleshoot my program, so please let me know which specific details would be useful to you and I will provide them.

    Thank you very much for any help.
  • kreagan
    New Member
    • Aug 2007
    • 153

    #2
    Originally posted by tekninja
    I wrote a very simple instant messenger client but, unfortunately, since I am still a relatively new programmer I am not familiar with what causes a program to eat up so much CPU time. Currently at runtime my program takes up 11mb in memory and 90-100% cpu usage!!

    Without posting all the code, what factors contribute to cpu usage? I am not really sure what information would help others troubleshoot my program, so please let me know which specific details would be useful to you and I will provide them.

    Thank you very much for any help.
    I experienced high CPU usage in very long for loops or never ending loops.

    Because your program takes up so much memory, are you creating many objects? Like MANY objects? Many BIG objects? Let me give you an example. I had 1 project run out of memory (Java has a cap on how much memory is used). We had to store a graph of 100,000 nodes. Yes, 100,000 huge objects.

    I also created a Sudoku solver that used large objects too - 89 of them. This program didn't take much memory.

    Does anyone know if a stack will cause a memory increase?

    Comment

    • tekninja
      New Member
      • Aug 2007
      • 4

      #3
      There are several objects... mainly objects used to deal with network connectivity and IO.

      However the program is basically one recurring loop (until the user quits the chat client). This is unavoidable since it must be constantly looping and dealing with asynchronous network input as well as user keyboard input...

      I am guessing then it is this loop that causes the high CPU usage? Are there any strategies for minimizing CPU usage?

      Comment

      • JosAH
        Recognized Expert MVP
        • Mar 2007
        • 11453

        #4
        Originally posted by tekninja
        There are several objects... mainly objects used to deal with network connectivity and IO.

        However the program is basically one recurring loop (until the user quits the chat client). This is unavoidable since it must be constantly looping and dealing with asynchronous network input as well as user keyboard input...

        I am guessing then it is this loop that causes the high CPU usage? Are there any strategies for minimizing CPU usage?
        Are you actively waiting/checking whether or not some data is coming in from
        the client(s)? If so, my bet would be on that for the high cpu utilization.

        Better use separate threads per open socket and let them block in a read
        method request. If the read blocks (because of no input) the thread will
        relinguish the cpu and other threads will have a chance. Most of the time
        none of them will be active.

        kind regards,

        Jos

        Comment

        • kreagan
          New Member
          • Aug 2007
          • 153

          #5
          Originally posted by JosAH
          If the read blocks (because of no input) the thread will
          relinguish the cpu and other threads will have a chance.
          Though that will definately need to be done for multiple clients, you can also block without threading.

          I'm assuming you are using BufferReader.
          [CODE=c]while ((userInput = stdIn.readLine( )) != null) {
          // do stuff
          }[/CODE]

          This while loop will block also.

          Comment

          • JosAH
            Recognized Expert MVP
            • Mar 2007
            • 11453

            #6
            Originally posted by kreagan
            Though that will definately need to be done for multiple clients, you can also block without threading.

            This while loop will block also.
            Sure, if a thread has compadres it doesn't suddenly start to behave differently;
            reads will block if there's no incoming data available. The op should made his/her
            threads block (read: relinguish control) when no data is available), whether there's
            one thread or more of them.

            kind regards,

            Jos

            Comment

            • kreagan
              New Member
              • Aug 2007
              • 153

              #7
              Originally posted by JosAH
              The op should made his/her threads block (read: relinguish control) when no data is available), whether there's one thread or more of them.
              Actually, I made this same mistake before.
              [CODE=java]while ( userInput == null ){
              userInput = stdln.readLine( );
              }[/CODE]

              If I remember correctly (this was 2 years ago) the above code will never block; you must use the while condition I posted above.

              Comment

              • tekninja
                New Member
                • Aug 2007
                • 4

                #8
                Originally posted by JosAH
                Are you actively waiting/checking whether or not some data is coming in from
                the client(s)? If so, my bet would be on that for the high cpu utilization.

                Better use separate threads per open socket and let them block in a read
                method request. If the read blocks (because of no input) the thread will
                relinguish the cpu and other threads will have a chance. Most of the time
                none of them will be active.

                kind regards,

                Jos
                Thanks for the replies guys... that is exactly what I am doing. Unfortunately the solutions above, while making some sense are a little confusing to me (quite the programming nub unfortunately).


                The client is very simple ( and the server likewise) there is only one socket connection (ie one host:port )

                right now I have methods checking for network input and/or keyboard input in the same while loop... in fact the method handling keyboard and/or net io is so simple I may as well post it:

                Code:
                try {
                
                while (!exit) {
                	if (scanKB.hasNextLine()) {
                		kbInput = scanKB.nextLine();
                		if (kbInput.equals("/quit")) {
                			switch (imc.disconnect()) {
                				case NO_ERRORS:
                					System.out.println("\nSuccessfully logged off");
                					break;
                				case IO_ERROR:
                					System.out.println("\nError while logging off");
                					break;
                			}
                			exit = true;
                		} else {
                			imc.sendMsg(kbInput);
                		}
                	}
                	if (imc.scanNet.hasNextMessage()) {
                		System.out.println(imc.printMsg(imc.scanNet.nextMessage()));
                	}
                }
                
                } catch (NextDoesNotExistException e) {
                	System.out.println("Error");
                } catch (NullPointerException e) {}
                So even with your examples above, I really am not sure what I could do with the above code to decrease CPU usage time...

                EDIT: Ok, for some reason I cannot fix line 21 in my code above... for some reason it is posting a space in the nextMessage() method... no matter what I do I can't get it to post that line correctly... so please just realize that there shouldn't be a space there...

                Also out of curiousity, how are you getting your code to post as java code with syntax coloring? I tried [JAVA][/JAVA] in place of [CODE] but that didn't work

                Thanks!

                Comment

                • Nepomuk
                  Recognized Expert Specialist
                  • Aug 2007
                  • 3111

                  #9
                  Originally posted by tekninja
                  Also out of curiousity, how are you getting your code to post as java code with syntax coloring? I tried [JAVA][/JAVA] in place of [CODE] but that didn't work

                  Thanks!
                  I guess, I'm not the right one to answer the question about multithreading, as it's something I've just started learning myself, but I can help you with your forum-related question: Just use [CODE=java] instead of [CODE] (but close it with the normal closing tag). That will also work with xml, html and many others... check the Code tag list to find all of them.

                  Greetings,
                  Nepomuk

                  Comment

                  • JosAH
                    Recognized Expert MVP
                    • Mar 2007
                    • 11453

                    #10
                    Originally posted by tekninja
                    So even with your examples above, I really am not sure what I could do with the above code to decrease CPU usage time...
                    Basically, what that while loop does is this:

                    [code=java]
                    while (<some condition>) {
                    if (<input from keyboard>)
                    processKeyboard Input();
                    if (<input from socket>)
                    processSocketIn put();
                    }
                    [/code]

                    Suppose no keyboard input nor socket input are available, i.e. nothing happens.
                    Can you see that loop running around in, well, loops, doing totally nothing?
                    That's where your CPU load comes from.

                    If you had two threads instead, one watching (and blocking for) the keyboard and
                    the other doing the same with the socket both threads would simply block if
                    no input were available and CPU usage would be down to almost zero.

                    kind regards,

                    Jos

                    Comment

                    • kreagan
                      New Member
                      • Aug 2007
                      • 153

                      #11
                      Originally posted by tekninja
                      Thanks for the replies guys... that is exactly what I am doing. Unfortunately the solutions above, while making some sense are a little confusing to me (quite the programming nub unfortunately).


                      The client is very simple ( and the server likewise) there is only one socket connection (ie one host:port )

                      right now I have methods checking for network input and/or keyboard input in the same while loop... in fact the method handling keyboard and/or net io is so simple I may as well post it:

                      Code:
                      try {
                      
                      while (!exit) {
                      	if (scanKB.hasNextLine()) {
                      		kbInput = scanKB.nextLine();
                      		if (kbInput.equals("/quit")) {
                      			switch (imc.disconnect()) {
                      				case NO_ERRORS:
                      					System.out.println("\nSuccessfully logged off");
                      					break;
                      				case IO_ERROR:
                      					System.out.println("\nError while logging off");
                      					break;
                      			}
                      			exit = true;
                      		} else {
                      			imc.sendMsg(kbInput);
                      		}
                      	}
                      	if (imc.scanNet.hasNextMessage()) {
                      		System.out.println(imc.printMsg(imc.scanNet.nextMessage()));
                      	}
                      }
                      
                      } catch (NextDoesNotExistException e) {
                      	System.out.println("Error");
                      } catch (NullPointerException e) {}
                      So even with your examples above, I really am not sure what I could do with the above code to decrease CPU usage time...


                      Thanks!
                      The quickest way to fix your program: Place the nextLine() in the while loop condition.

                      [CODE=java]while ( ( (kbInput = scanKB.nextLine ()) != null ) ||
                      ( (imcInput = imc.scanNet.nex tMessage()) != null) ){
                      if (kbInput.equals ("/quit")) {
                      .... //finish code. [/CODE]

                      I would suggest reading this tutorial Sockets but focus on the last section - Supporting Multiple Clients. This is a great example of threads.

                      Comment

                      • JosAH
                        Recognized Expert MVP
                        • Mar 2007
                        • 11453

                        #12
                        Originally posted by kreagan
                        Actually, I made this same mistake before.
                        [CODE=java]while ( userInput == null ){
                        userInput = stdln.readLine( );
                        }[/CODE]

                        If I remember correctly (this was 2 years ago) the above code will never block; you must use the while condition I posted above.
                        That most certainly isn't true; a readLine() method invocation will block when there
                        is no new line available. Your loop is exactly the same (functionally) as the loop
                        you don't like.

                        kind regards,

                        Jos
                        Last edited by JosAH; Sep 13 '07, 02:29 PM. Reason: typo again ...

                        Comment

                        • kreagan
                          New Member
                          • Aug 2007
                          • 153

                          #13
                          Originally posted by JosAH
                          That most certainly isn't true; a readLine() method invocation will block when there
                          is no new line available. Your loop is exactly the same (functionally) as the loop
                          you don't like.

                          kind regards,

                          Jos
                          Thanks for fixing my confusion.

                          Comment

                          Working...