Ho un server di gioco JAVA che utilizza 1 thread per connessione TCP. (So che è male ma dovrò tenerlo così per ora). Su una (macchina 3.2Ghz 6cor x2, RAM 24GB, Windows Server 2003 64bit) e qui è un pezzo di codice:BufferedReader.read() mangia il 100% della CPU
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);
}
}
Dopo circa 12 ore o più di uptime del server (e circa 3.000 giocatori collegati) il il server inizia a mangiare il 100% di tutte le 12 CPU per sempre, fino a quando non riavvio manualmente l'applicazione JAVA. In questo modo il gioco inizia a rallentare e i miei giocatori iniziano a lamentarsi.
Ho provato profiling l'applicazione e qui è quello che mi si avvicinò con:
Così sto indovinando che il problema viene da qui:
while(_in.read(charCur, 0, 1)!=-1 && Server.isRunning)
sapendo che il variabile "_in" è un lettore dell'ingresso socket: (_in = new BufferedReader (new InputStreamReader (_socket.getInputStream())))).
Perché on-_y.read() richiede così tanta CPU dopo un lungo server upTime?
Ho provato a mettere un Thread.sleep (1); e più all'interno del ciclo While, ma non fa nulla, immagino che il problema sia all'interno del metodo BufferedReader.read().
Qualcuno ha qualche idea di cosa può causare questo ?? E come ripararlo?
Sono sorpreso che sia questo piuttosto che il fatto che si sta utilizzando la concatenazione di stringhe in un ciclo. E * perché * stai leggendo solo un singolo personaggio alla volta? –
i pacchetti sono stringhe molto piccole come: "AB123". quindi non importa. – Reacen
Fino a quando non viene inviata una stringa enorme da qualcuno che lancia un attacco DDOS su di te. È così facile leggere più caratteri e * anche * usare StringBuilder ... perché non farlo? –