2010-06-08 69 views
0

我有一個簡單的UDP服務器,它創建一個處理傳入數據的新線程。當通過發送大約100個數據包/秒進行測試時,我注意到它的內存使用量不斷增加。下面的代碼是否有任何泄漏?使用Java UDP服務器增加內存

這是服務器的代碼。

public class UDPServer 
{ 
    public static void main(String[] args) 
    { 
     UDPServer server = new UDPServer(15001); 
     server.start(); 
    } 

    private int port; 

    public UDPServer(int port) 
    { 
     this.port = port; 
    } 

    public void start() 
    { 
     try 
     { 
      DatagramSocket ss = new DatagramSocket(this.port); 

      while(true) 
      { 
       byte[] data = new byte[1412]; 
       DatagramPacket receivePacket = new DatagramPacket(data, data.length); 
       ss.receive(receivePacket); 
       new DataHandler(receivePacket.getData()).start(); 
      } 

     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

} 

這是處理數據的新線程的代碼。現在,run()方法不起任何作用。

public class DataHandler extends Thread 
{ 
    private byte[] data; 

    public DataHandler(byte[] data) 
    { 
     this.data = data; 
    } 

    @Override 
    public void run() 
    { 
     System.out.println("run"); 
    } 

} 

回答

5

當然,你在每個循環中分配(至少)1412字節的新內存。在GC啓動並清理所有未使用的分配數據之前,您會看到內存使用量增加。

使用像Java VisualVM這樣的內存分析器可視化並分析行爲。

+0

JConsole在這種情況下會更好,因爲它包含了所有伊甸園,倖存者和舊版堆大小的視圖。另外,你可以強烈建議一個gc。 – 2010-06-10 04:30:43

-1

爲什麼你的代碼中有一個無限循環。你不能在一個單獨的線程中運行它。另外,這行byte [] data = new byte [1412];將分配一些字節,直到無限循環開始纔會釋放。

+0

循環將等待接收傳入數據包,創建一個新線程來處理數據,然後再次啓動循環以等待另一個傳入數據包。 ' – Trevor 2010-06-08 19:21:15

+0

'新字節[1412];將分配一些不會被釋放的字節'。不正確。該參考將在循環中每次發佈。線程中的其他引用將在線程退出時釋放。我同意另一張海報,你不應該使用每個數據包的線程。根據處理的內容,您可能根本不需要新的線程:否則,請考慮使用每個遠程SocketAddress的線程。 – EJP 2010-06-08 23:47:45

1

您正在爲每個數據包分配一個新線程。線程分配並不便宜。您可以嘗試使用一個線程池,並將數據包交給從池中取出的工作線程(請參閱java.util.concurrent以獲得一些有用的幫助)。