問題的簡短摘要:我創建的tcp服務器每秒接收一個來自發送大約5kb xml和斷開連接的客戶端的連接,但隨着時間的推移,內存在內存中不斷增加,即使我沒有在任何地方存儲xml。C#字符串導致TCP服務器內存泄漏?
我有一個簡單的TCP服務器,我有一個線程在while循環中調用AcceptTcpClient(),然後用新的TcpClient調用ThreadPool.QueueUserWorkItem(HandleTcpClient,tcpClient)。
在功能現在,線程池運行(如:HandleTcpClient)我做了以下內容:
int bytesRead = networkStream.Read(byteBuffer, 0, 8000);
if (bytesRead == 0) return null;
return encoder.GetString(byteBuffer, 0, bytesRead);
之後,其調用,確實在隊列上的鎖(),並增加了消息的功能到隊列。表單上的另一個線程每隔50ms檢查一次隊列,調用lock()並彈出字符串。
目前,我剛流行過的字符串,然後執行:
XElement xe = XElement.Parse(msg);
xe = null;
當我啓動該程序,私營集存儲爲34MB,在10小時內,內存使用率達到251MB。我在窗體上做了一個菜單項,我可以點擊它來調用GC.Collect(),但是這隻能削減2MB的內存,然後程序開始再次增長。
我不知道爲什麼內存會不斷增長,因爲不斷創建的字符串應該被丟棄,而且我不會將任何東西不斷放在堆上。
我使用了.NET Memory Profiler,它顯示字符串char生存實例不斷增加。
我認爲創建一個新的字節數組可能會導致內存泄漏,所以我創建了一個快速的字節緩衝區類,如下所示。任何想法爲什麼記憶保持增長?
class ByteBuffer { static Dictionary<object, byte[]> buffers = new Dictionary<object,byte[]>();
static public void Allocate() {
for (int i = 0; i < 90; i++)
{
buffers.Add(new object(), new byte[8000]);
}
}
static ASCIIEncoding encoder = new ASCIIEncoding();
static public string GetMessage(NetworkStream ns)
{
foreach (object o in buffers.Keys)
{
bool lockTaken =false;
Monitor.TryEnter(o,TimeSpan.FromMilliseconds(15), ref lockTaken);
if (lockTaken)
{
try
{
int bytesRead = ns.Read(buffers[o], 0, 8000);
if (bytesRead == 0) return null;
return encoder.GetString(buffers[o], 0, bytesRead);
}
catch
{
return null;
}
finally
{
Monitor.Exit(o);
}
}
}
return null;
} }
你的內存分析器不能追蹤引用了哪些字符串?如果你有這樣的截圖,那會有很大的幫助。 – 2012-01-10 18:33:28
服務器是否讀取很多不同形式的XML,或者大多數文檔是否具有相同的元素和屬性名稱?你是否手動彙集你的名單? – 2012-01-10 18:42:17
我想知道是什麼調用GetMessage以及如何管理顯示代碼之外的字符串。你應該回TRY塊嗎? – Bengie 2012-01-10 18:54:52