2014-04-29 69 views
0

我有一個WinForm應用程序,它定期輪詢TCP服務器並下載一些用戶數據(JSON表示法)。出於某種原因,與下面的方法每次調用該應用程序增加內存使用情況:WebClient.DownloadString()的內存泄漏/分配問題?

private void timerElapsed(object sender, ElapsedEventArgs e) 
    { 
     if (!isPolling) 
     { 
      isPolling = true; 

      try 
      { 
       using (System.Net.WebClient wc = new System.Net.WebClient()) 
       { 
        jsonTemp = wc.DownloadString(serverUrl); 

        isPolling = false; 
       } 
      } 
      catch (Exception ex) 
      { 
       isPolling = false; 
      } 
     } 
     else 
     { 
      isPolling = false; 
     } 
    } 

每當wc.DownloadString被調用,我的應用增加足跡。

由於WebClient已經實現了IDisposable,它應該在using指令後自動處理,還是我錯了?

+0

你如何檢查內存使用情況?例如,虛擬內存可能會增加,因爲即使垃圾收集器處理它們,也會創建大量臨時對象。它只是沒有返回到系統,因爲它可能沒有必要。 –

+0

目前,我只觀察Windows任務管理器中的值。但是,.Net Memory Profiler也會報告增加的值。我想這是用perfmon再次檢查內存使用情況以獲取更多信息。 – lenniep

+2

是的,我會繼續進行perfmon分析,並且在程序運行很長時間後(爲了有清楚的情況)會花費全部內存轉儲。 –

回答

1

那麼,這是可以預料的。內存使用量只會在垃圾回收後下降。這不是C或Pascal - 當變量超出範圍或塊結束時內存不會釋放 - 內存僅在內存壓力下釋放(.NET模型使分配極其便宜,而集合相對昂貴,並且實際上並沒有太多依賴於你總共釋放了多少內存 - 因此,犧牲一些MiB讓內存中的垃圾長時間存放並且一次釋放100個對象要快得多,而不是一次收集100次)。

我們在這裏談論的數字有多大? MiBs不值得關注,它只有在平均穩定攀升(超過數十萬次通話)時纔會開始尋找泄漏。另外,你在檢查什麼樣的內存?私人內存?虛擬內存?委託記憶?

如果垃圾收集在內存中存在固定句柄時啓動,則可能會發生內存泄漏 - 這會阻止堆壓縮發作。您可以在CLRProfiler中輕鬆查看。但是,再一次,如果堆碎片變得太高,這真的非常重要。

至於IDisposable和GC,我已經得到了這樣的回答:Does the "using" keyword mean the object is disposed and GC'ed?

+0

延遲響應比沒有響應更好。Luaan指出了正確的方向 - 似乎GC讓對象活得更長一些,而在多天運行測試期間,內存使用停止攀升。 – lenniep