BufferedReader.read () verbraucht 100% der CPU

9

Ich habe einen JAVA-Spieleserver, der 1 Thread pro TCP-Verbindung verwendet. (Ich weiß, es ist schlecht, aber ich muss es jetzt so halten). Auf einem (3.2Ghz 6cor x2 Maschine, 24GB RAM, Windows Server 2003 64bit) und hier ist ein Stück des Codes:

%Vor%

Nach ungefähr 12 Stunden oder mehr von Server upTime (und ungefähr 3.000 angeschlossenen Spielern) beginnt der Server 100% aller 12 CPUs für immer zu essen, bis ich die JAVA-Anwendung manuell neu starte. Das Spiel beginnt also sehr schlecht und meine Spieler beginnen sich zu beschweren.

Ich habe versucht, die Anwendung zu profilieren und hier ist, was ich gefunden habe:

Ich vermute also, dass das Problem von hier kommt:

%Vor%

zu wissen, dass die Variable "_in" ein Leser der Socket-Eingabe ist: (_in = new BufferedReader (new InputStreamReader (_socket.getInputStream ()))).

Warum in der Welt _in.read () nimmt so viel CPU nach einem langen Server upTime?

Ich habe versucht, einen Thread.sleep (1) zu setzen; und mehr innerhalb der While-Schleife, aber tut nichts, ich denke, das Problem ist innerhalb der BufferedReader.read () -Methode.

Hat jemand eine Idee, was das bewirken kann ?? Und wie man es repariert?

    
Reacen 02.09.2011, 09:12
quelle

5 Antworten

3

Dies ist ein Duplikat Ihrer vorherigen Frage: Eine Endlosschleife irgendwo in meinem Code . Bitte öffnen Sie keine neue Frage, sondern verwenden Sie stattdessen die Bearbeitungsfunktionen.

Das heißt, 3000 Threads sind definitiv eine Menge und würden höchstwahrscheinlich eine übermäßige Menge an Kontextwechsel verursachen. Statt einen neuen Thread für jede Verbindung zu starten, sollten Sie in Java nicht blockierende IO-Einrichtungen verwenden. Beispiele finden Sie hier: Ссылка

    
Lauri Piispanen 02.09.2011 14:12
quelle
1

Ich weiß nicht, warum der Anruf langsam ist, aber ich würde niemals ein Byte in einer engen Schleife lesen. Wer weiß, welche Art von Overhead die interne Funktion hat.

Ich würde alle Daten lesen, die momentan im Stream verfügbar sind, und das analysieren. Dies würde einen Puffer und eine zusätzliche Buchhaltung erfordern, aber trotzdem schneller als Byte für Byte aus einem Stream zu lesen.

    
Roel Van Nyen 02.09.2011 09:29
quelle
0
  

'1 Thread pro TCP-Verbindung'   'etwa 3.000 Spieler verbunden'

= 3.000 Threads?!

Meine Vermutung: Die maximale Anzahl der Threads, die wiederholt jeweils ein Byte kopieren können, liegt bei etwa 3.000. Das klingt nicht so komisch.

Lösung: weniger Threads und lesen Sie mehr Bytes auf einmal.

Sie könnten einen ExecutorService verwenden. Es gibt ein vereinfachtes Beispiel im Javadoc: Ссылка

    
Ishtar 02.09.2011 09:37
quelle
0

Es sieht nicht so aus, als ob Sie den BufferedReader jemals schließen, außer Sie versuchen es in der Methode buckPlayer ().

Jeder Leser kann viel länger leben, als Sie wissen.

    
FacilityDerek 02.09.2011 10:11
quelle
0

Ich glaube, ich bin mit dem gleichen Problem konfrontiert, und ich vermute, es ist ein Bug in Java. Ich habe meine Frage an BufferedReader.read () gestellt, die 100% der CPU verbraucht - vielleicht gibt jemand dort eine Antwort und das wird dir auch helfen.

    
Esko Luontola 16.04.2012 16:44
quelle