我有一個Java客戶機(在Windows XP上的1.6b17,通過Java webstart啓動),它使用TCP套接字通過ADSL連接查詢基於Java的服務器。客戶端套接字有一個超時設置(3000毫秒)。設置超時設置的套接字有時會在閱讀時失速
偶爾(到目前爲止,不能重現),客戶端在讀取來自服務器的響應時停頓。有幾百次安裝,大多數用戶大多數時間都沒有遇到這個問題。
的客戶端按照以下步驟每個請求創建一個新的socket:
- 創建一個新的套接字設置超時時間爲3000ms
- 提交請求(文字單行)
- 閱讀多行響應,當收到特殊的「消息結束」序列時(或空),關閉套接字
下面是一些(簡化的)代碼來說明:
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分鐘,然後恢復,不需要任何干預。在此之後,應用程序將繼續執行,但不會有明顯的性能問題。
在服務器端登錄表明該操作大約需要150ms,儘管在關閉套接字之前採取了有關時間戳(我將嘗試解決這個問題)。
我的工作假設之一是,這不是由於網絡問題,否則,readLine會超時,這是一個有效的假設嗎?
這似乎不可能是垃圾收集相關。該應用程序有512MB分配給堆,而正在檢索的數據由大約1600行100個字符組成。我的期望是,如果與GC或內存泄漏有關的問題會導致性能的普遍下降,而不是我所看到的那種「粘性」行爲,這是正確的嗎?
任何建議的策略來解決這個問題將不勝感激。
感謝, 菲爾
套接字是否在客戶端自己的線程中讀取? –
這是在美國東部時間,不理想,但不是我現在可以改變的東西。 – PhilDin
您是否曾嘗試通過設置客戶端並一次又一次地執行請求來重現問題? –