我有一个Java客户端(Windows XP上的1.6b17,通过Java webstart启动),它使用TCP套接字通过ADSL连接查询基于Java的服务器。客户端套接字具有超时设置(3000毫秒)。
偶尔(并且到目前为止,不可重复),客户端在从服务器读取响应时停止。有几百个安装,大多数用户大多数时间都没有遇到这个问题。
客户端按照以下步骤为每个请求创建一个新套接字:
这里有一些(简化的)代码来说明:
socket = new Socket(host, port);
socket.setSoTimeout(socketTimeout);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
socket.write(cmd);
while (true) {
line = in.readLine();
if (line == null) break;
if (line.equals("EOL")) break;
// Store line of text in an ArrayList
}
socket.close();
问题在于,偶尔在接收过程中,客户端将暂停最多5分钟,然后在没有任何干预的情况下恢复。在此之后,应用程序恢复,没有明显的性能问题。
登录服务器端表示操作大约需要150毫秒,尽管有问题的时间戳是在关闭套接字之前采取的(我将尝试解决这个问题)。
我的一个假设是,这不是由于网络问题,否则readLine会超时,这是一个有效的假设吗?
这似乎也不太可能与垃圾收集相关。该应用程序有512MB分配给堆,而被检索的数据包含大约1600行100个字符。我的期望是,如果与GC或内存泄漏有关的问题是性能普遍下降而不是我所看到的那种“粘性”行为,这是正确的吗?
非常感谢任何建议的故障排除策略。
谢谢, 菲尔
答案 0 :(得分:2)
我没有看到你达到5分钟的“暂停”。我只能想象你在数据包上得到了很多重试。你应该能够通过wireshark看到类似的东西。它可以为你提供其他东西的线索。
512 MB堆上的完整GC暂停时间应为0.5秒左右(非常接近)
如果您的连接不可靠,我建议您不要使用PrintWriter。如果它获得IOException,它会设置一个标志而不是抛出异常。如果你继续使用它,它什么都不做。
答案 1 :(得分:1)
readLine()
应该超时。在任何平台上都没见过不行。也许你一次只收到一个角色,间隔不到3秒。 Wireshark会告诉你。
或者当你正在读行时,服务器可能没有在正确的位置发送换行符?