2017-08-17 146 views
2

我正在做我的第一步與C#中的異步/等待,爲此我想寫一個簡單的TCP服務器接收簡單的字符串(現在)。 因此,我設置了一個Windows服務,其中包含一個循環,用於監聽傳入連接,接受這些連接並關閉套接字(我打算將字符串寫入日誌文件或其他東西,但這必須等到問題出現爲止我即將形容解決)。異步TCP服務器(Windows服務)內存泄漏

無論如何,問題是,在網絡上收到一些字符串後,我的服務正在佔用內存,而這些內存在以後不會發布。當我啓動服務並且沒有連接時,該過程需要4.716K。當連接被接受時,這個數量會增加(正如我所預料的那樣),但是這些資源看起來並不會被釋放......

可能我忽略了某些東西,但是我找不到解決方案(儘管「項目」包含只有幾行代碼現在),因此我將非常感謝您的幫助,夥計們:/

這些都是啓動/關閉事件處理程序:

protected override void OnStart(string[] args) 
{ 
    this.listener = new TcpListener(IPAddress.Any, 7777); 
    this.listener.Start(); 

    this.worker = new Thread(StartServer); 
    this.worker.Start(); 
} 

protected override void OnStop(string[] args) 
{ 
    this.serviceIsRunning = false; 
    this.worker.Join(); 

    // TODO: Cancellation token maybe? 
} 

而這個服務器循環:

private async void ServerStart(object arguments) 
{ 
    while (serviceIsRunning) 
    { 
     TcpClient client = await listener.AcceptTcpClientAsync(); 
     Task requestTask = HandleRequest(client); 
    } 

    this.listener.Stop(); 
} 

連接處理器:

private async Task HandleRequest(TcpClient client) 
{ 
    using (var stream = new StreamReader(client.GetStream(), Encoding.UTF8)) 
    { 
     // Do something with it 
     string request = await stream.ReadToEndAsync(); 
    } 

    // Gracefully close connection 
    client.Close(); 
} 

謝謝!

+3

4.7KB(你的意思是MB?)使用過的內存沒有多少說明,因爲GC可能認爲它不值得運行一個集合。您可以嘗試手動添加'GC.Collect()'調用並查看是否釋放內存,但是在分析應用程序並查看是否有任何對象位於手動強制集合後不再使用的情況下(他們的參考樹一直到應用程序根目錄)。 – easuter

回答

2

內存使用率很低。我已經看到垃圾回收器等待,直到我有2個千兆字節的內存被3D模型/圖像消耗後纔會運行。如果隨着時間的推移觀察應用程序的行爲,您會在大量運行中看到高峯和低谷。我建議兩個實驗。

  1. 啓動任務管理器,在怠速運行過程幾秒鐘,然後從服務器發送數據的一些大的爆發,使得該請求是圍繞100-1000倍進行處理,然後讓它繼續開了幾秒鐘後關閉它。內存使用應該返回到您的應用程序打開之前的位置。

  2. 遵循幾乎相同的過程,但是這次在處理請求(GC.Collect())後調用垃圾回收器。檢查您的內存使用情況是否與此次不同。

如果這不能按預期工作,請嘗試創建和銷燬您的TCP服務器類。內存使用情況應該恢復正常。這將問題隔離到您的班級或垃圾收集器。