我有一個JAVA遊戲服務器,每個TCP連接使用1個線程。 (我知道這很糟糕,但現在我必須保持這種狀態)。上的(3.2Ghz的6cor X2機,24GB RAM,Windows Server 2003和的64位),並在這裏是一塊代碼:BufferedReader.read()吃了100%的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);
}
}
服務器運行時間約12小時或更長時間(約3.000玩家連接)後,將服務器開始吃掉所有12個CPU的100%,直到我手動重新啓動JAVA應用程序。所以比賽開始落後嚴重,我的球員開始抱怨。
我試圖分析應用程序和這裏是我想出了:
所以我猜這個問題是從這裏來的:
while(_in.read(charCur, 0, 1)!=-1 && Server.isRunning)
明知變量「_in」是套接字輸入的讀取器:(_in = new BufferedReader(new InputStreamReader(_socket.getInputStream())))。
爲什麼在長時間的服務器uptime之後,_in.read()需要很多CPU?
我試過把Thread.sleep(1);和更多內部的循環,但沒有做任何事情,我猜這個問題是在BufferedReader.read()方法中。
有沒有人有什麼可以導致這種情況?以及如何解決它?
我很驚訝它的這個,而不是事實,你使用字符串連接在一個循環。 *爲什麼*你一次只能讀一個字符? –
數據包非常小,例如:「AB123」。所以沒關係。 – Reacen
直到你最終被髮送一個巨大的字符串被某人發動DDOS攻擊。讀取多個字符和*還可以使用StringBuilder非常簡單...爲什麼不這樣做呢? –