2013-12-09 50 views
1

我想使一個服務器,可以有多個用戶,即時只創建2個線程,但我的BufferedReader.readLine()似乎是使多個線程和導致OutOfMemory異常,我不明白爲什麼它這樣做?BufferedReader.readLine()創建線程()?

功能造成例外:

public void run() { 
    try { 
     Username = Input.readLine(); 
    } catch (IOException e1) { 
     disconnect(); 
    } 
    String lastInput = null; 
    try { 
     while ((lastInput = Input.readLine()) != null) { 
      System.out.println(lastInput); 
      if (lastInput.startsWith("Chat: ")) { 
       sendToAllClients(lastInput.substring(7)); 
      } 
     } 
    } catch (IOException e) { 
     disconnect(); 
    } 
} 

除外:

Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space 
at java.util.Arrays.copyOf(Unknown Source) 
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source) 
at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source) 
at java.lang.AbstractStringBuilder.append(Unknown Source) 
at java.lang.StringBuffer.append(Unknown Source) 
at java.io.BufferedReader.readLine(Unknown Source) 
at java.io.BufferedReader.readLine(Unknown Source) 
at Main.User.run(User.java:46) 
at java.lang.Thread.run(Unknown Source) 

注意:用戶名= Input.readLine()被使異常

+1

你不應該吞嚥這樣的例外...... – Sinkingpoint

+0

我不知道你爲什麼要嘗試處理異常處理程序中的'lastInput' ...... – MadProgrammer

回答

1

要避免無限循環,因此您的OOM例外:

try{ 
    while ((currentInput=Input.readLine()) != null) { 
    if (currentInput.startsWith("Chat: ")) 
     sendToAllClients(currentInput.substring(7)); 
    } 
catch (IOException e) { //bad to swallow exception: let's the method throw it or make something with it here} 
-1

Out of memory heap space進入畫面是程序正在無限循環。

您的代碼:

while (true) { 
     try { 
      lastInput = Input.readLine(); 
     } catch (IOException e) {} 
     if (lastInput != null) { 
      System.out.println(lastInput); 
      if (lastInput.startsWith("Chat: ")) { 
       sendToAllClients(lastInput.substring(7)); 
      } 
     } 

說,循環內的代碼將運行無限多次,而不作爲退出條件的任何條件。即使出現問題:您正捕獲該異常並且代碼在循環內部繼續保持。

這導致Out of Memory : Heap Space.

Suggesed解決方案:

while (true) 
{ 
    try 
    { 
     lastInput = Input.readLine(); 
    } 
    catch (IOException e) 
    { 
    break; 
    } 
    if (lastInput != null) 
     { 
      System.out.println(lastInput); 
      if (lastInput.startsWith("Chat: ")) 
      { 
      sendToAllClients(lastInput.substring(7)); 
      } 
     } 
} 

這個循環將打破儘快用戶輸入導致異常的任何名稱(事實上,作爲退出條件的敵人while循環)

編輯

一個領域,我看可能是在S問題的烏爾斯河可能是:

lastInput.substring(7) 

如果lastInput字符串是規模龐大,幾乎可以填補裝系統,然後調用從7th character to the last character一個substringheap space of the JVM的,會在內部引發新的String創建(因爲字符串是不可變的),&沒有足夠的剩餘空間,substring執行給出OutOfMemory exception

+0

我並不積極,但我認爲無限循環試圖讓程序保持活躍狀態​​,像服務器一樣工作。 –

+0

我更改了while循環,但用戶名get是執行Exception的行。 – user2601014

+0

如果readLine()返回null,則此代碼必須分解出來。否則它是無用的。 -1 – EJP

-1

第一:檢查你的程序的while循環。 秒:設置參數集JAVA_OPTS = -Xms32m -Xmx512m。

+0

我設置了Xms和Xmx,希望它能夠修復它。它的Username = Input.readLine()使得異常不在while循環中 – user2601014

+0

檢查while循環如何? – EJP

0

readLine()不創建線程。

如果'lastInput'爲null,則應退出循環並關閉流。

如果您遇到異常,請將其記錄或打印出來,關閉流並斷開。

+0

循環將在客戶端發送到服務器時獲取來自客戶端的所有輸入。所以它只是打印它。問題不是循環,它的獲取用戶名= Input.readLine() – user2601014

+0

當readLine()返回null時,那麼*是*沒有更多的輸入。以後再。你可以隨時嘗試,而不是毫無意義地爭論。如果你的代碼是完美的,你就不必提問這個問題。 – EJP