我有一个JAVA游戏服务器,每个TCP连接都使用1个线程。(我知道这是不好的,但现在我必须保持这种方式)。在一台(3.2Ghz 6核x2机器,24GB RAM,Windows Server 2003 64位)上,以下是一段代码:
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()))).
为什么长时间运行后,_in.read()会占用很多CPU资源?
我已经尝试在While循环中加入Thread.sleep(1)等操作,但没有任何效果,我猜问题出在BufferedReader.read()方法内部。
有没有人知道这是什么原因?如何解决?