Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BufferedReader.read() eating 100% of CPU

I have a JAVA game server that uses 1 thread per TCP connection. (I know it's bad but i'll have to keep it this way for now). On a (3.2Ghz 6cor x2 machine, 24GB RAM, windows server 2003 64bits) and here is a piece of the code:

public void run()
{
    try
    {   
        String packet = "";
        char charCur[] = new char[1];

        while(_in.read(charCur, 0, 1)!=-1 && Server.isRunning)
        {
            if (charCur[0] != '\u0000' && charCur[0] != '\n' && charCur[0] != '\r')
            {
                packet += charCur[0];
            }else if(!packet.isEmpty())
            {
                parsePlayerPacket(packet);
                packet = "";
            }
        }

    }catch(Exception e)
    {
        e.printStackTrace();
    }
    finally
    {
        try{
            kickPlayer();
        }catch(Exception e){e.printStackTrace();};

        Server.removeIp(_ip);
    }
}

After about 12 hours or more of server upTime (and about 3.000 players connected) the server starts eating 100% of all the 12 CPUs for ever, until I manually reboot the JAVA application. So the game starts lagging verry bad and my players starts complaining.

I have tried profiling the application and here is what I came up with:

Screenshot of my profiling result

So I am guessing that the problem is coming from here:

while(_in.read(charCur, 0, 1)!=-1 && Server.isRunning)

knowing that the variable "_in" is a reader of the socket input : (_in = new BufferedReader(new InputStreamReader(_socket.getInputStream()))).

Why on earth _in.read() takes so much CPU after a long server upTime?

I have tried putting a Thread.sleep(1); and more inside the While loop, but doesn't do anything, I guess the problem is inside of the BufferedReader.read() method.

Does anyone have any idea of what can cause this?? And how to fix it?

like image 417
Reacen Avatar asked Sep 02 '11 09:09

Reacen


1 Answers

This is a duplicate of your previous question: An infinite loop somewhere in my code. Please do not open up a new question, but instead use the editing functions.

That being said, 3000 threads is definitely a lot and would most likely cause excessive amounts of context switching. Instead of starting a new thread for each connection, consider using non-blocking IO facilities in Java. Examples can be found here: http://download.oracle.com/javase/1.4.2/docs/guide/nio/example/index.html

like image 178
Lauri Piispanen Avatar answered Oct 17 '22 11:10

Lauri Piispanen