2013-05-15 24 views
0

這是一個帶有Socket連接的線程。Android:套接字連接導致時滯和很多GC動作

服務器向此套接字發送隨機int數(每10 ms)。 問題是,經過一段時間後,接收數據的巨大滯後和LogCat打印了大量的「GC_CONCURRENT釋放」消息。

public class TcpSocketThread extends Thread { 
Context context; 
String ip; 
int port; 

public TcpSocketThread(Context con, String ip, int port) { 
    context = con; 
    this.ip = ip; 
    this.port = port; 

} 

@Override 
public void run() { 
    Socket client; 

    try { 

     client = new Socket(ip, port); 
     BufferedReader in = new BufferedReader(new InputStreamReader(
       client.getInputStream())); 


     String msg; 
     while (true) { 

      if (in.ready()) { 
       msg = in.readLine(); 
       Intent intent = new Intent(BLUETOOTH_DATA); 
       intent.putExtra(BLUETOOTH_DATA_STRING, msg); 

       context.sendBroadcast(intent); 

       Log.v("Tcp-Socket-Thread", "msg: " + msg); 
      } 

     } 

    } catch (UnknownHostException e) { 
     Log.v("client", "unknown host" + e); 

    } catch (IOException e) { 
     Log.v("client", "No I/O" + e); 
    } 
} 

}

回答

0

你不應該重複輪詢ready()來測試是否有要讀取的數據。請致電readLine()。它會阻塞線程,直到有數據要讀取或連接關閉。

但我不認爲這是垃圾產生的原因。我懷疑這與你正在閱讀的文章正在做什麼有關。我知道使用意圖涉及Java對象流,並且它們在序列化和反序列化過程中使用的內存方面相當重。看起來你可以在多個地方進行反序列化...取決於什麼是監聽廣播的意圖。

1

您不應該反覆輪詢ready()以測試是否有要讀取的數據。只需調用readLine()。它會阻塞線程,直到有數據被讀取或連接關閉。

對於讀取塊是一個很好的建議,但是您每次處理數據時都會創建新的Intent,您是否可以重用該對象?這是導致GC瘋狂的部分。

希望這可以幫助和享受您的工作。