Я работаю над WebCrawler реализация, но столкнулся с странной утечкой памяти в ASP.NET Web API 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.
Я использую С# 4.0, поэтому нет async/await здесь, поэтому используется только TPL 4.0.
Приведенный выше код работает, но не оптимизирован, а иногда вызывает истерику, но для воспроизведения эффекта достаточно. Точка: я не могу найти точку, которая может вызвать утечку памяти.