我正在研究 WebCrawler实现,但在 ASP.NET Web API 的 HttpClient 中遇到了奇怪的内存泄漏。
所以精简版在这里:
[更新 2]
我发现了问题,不是 HttpClient 泄漏了。看我的回答。
[更新 1]
我添加了 dispose 没有效果:
static void Main(string[] args)
{
int waiting = 0;
const int MaxWaiting = 100;
var httpClient = new HttpClient();
foreach (var link in File.ReadAllLines("links.txt"))
{
while (waiting>=MaxWaiting)
{
Thread.Sleep(1000);
Console.WriteLine("Waiting ...");
}
httpClient.GetAsync(link)
.ContinueWith(t =>
{
try
{
var httpResponseMessage = t.Result;
if (httpResponseMessage.IsSuccessStatusCode)
httpResponseMessage.Content.LoadIntoBufferAsync()
.ContinueWith(t2=>
{
if(t2.IsFaulted)
{
httpResponseMessage.Dispose();
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine(t2.Exception);
}
else
{
httpResponseMessage.Content.
ReadAsStringAsync()
.ContinueWith(t3 =>
{
Interlocked.Decrement(ref waiting);
try
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(httpResponseMessage.RequestMessage.RequestUri);
string s =
t3.Result;
}
catch (Exception ex3)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(ex3);
}
httpResponseMessage.Dispose();
});
}
}
);
}
catch(Exception e)
{
Interlocked.Decrement(ref waiting);
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e);
}
}
);
Interlocked.Increment(ref waiting);
}
Console.Read();
}
包含链接的文件可在此处获得。
这导致内存不断上升。内存分析显示 AsyncCallback 可能持有许多字节。我之前做过很多内存泄漏分析,但这一次似乎是在 HttpClient 级别。
我使用的是 C# 4.0,所以这里没有 async/await,所以只使用了 TPL 4.0。
上面的代码有效,但没有优化,有时会发脾气,但足以重现效果。关键是我找不到任何可能导致内存泄漏的点。