Сканирование HttpClient приводит к утечке памяти
Я работаю над WebCrawlerреализация но сталкиваюсь со странной утечкой памяти в ASP.NET Web API 's HttpClient.
Итак, урезанная версия здесь:
[ОБНОВЛЕНИЕ 2]Я обнаружил проблему, и это не HttpClient, который протекает. Смотри мой ответ.
[ОБНОВЛЕНИЕ 1]Я добавил распоряжение без эффекта:
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, поэтому здесь нет асинхронных / ожидающих операций, поэтому используется только TPL 4.0.
Приведенный выше код работает, но не оптимизирован и иногда вызывает истерику, но этого достаточно для воспроизведения эффекта. Дело в том, что я не могу найти ни одной точки, которая могла бы вызвать утечку памяти.