gpt4 book ai didi

c# - HttpClient爬取导致内存泄漏

转载 作者:IT王子 更新时间:2023-10-29 04:38:38 30 4
gpt4 key购买 nike

我正在开发 WebCrawler implementation但是我在 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();
}

包含链接的文件可用here .

这导致内存不断上升。内存分析显示 AsyncCallback 可能持有许多字节。我之前做过很多内存泄漏分析,但这个似乎是在 HttpClient 级别。

Memory profile of the process showing buffers held possibly by async callbacks

我使用的是 C# 4.0,所以这里没有异步/等待,所以只使用了 TPL 4.0。

上面的代码有效但没有优化,有时会发脾气,但足以重现效果。关键是我找不到任何可能导致内存泄漏的点。

最佳答案

好的,我已经弄清楚了。感谢@Tugberk、@Darrel 和@youssef 在这方面花时间。

基本上,最初的问题是我生成了太多任务。这开始造成损失,所以我不得不减少它并有一些状态来确保并发任务的数量是有限的。 这对于编写必须使用 TPL 来安排任务的流程来说基本上是一个很大的挑战。我们可以控制线程池中的线程,但我们还需要控制我们正在创建的任务,因此任何级别的 async/await 都无济于事。

我用这段代码只成功地重现了几次泄漏——其他时候在增长之后它会突然下降。我知道 4.5 中对 GC 进行了改造,所以这里的问题可能是 GC 没有足够的启动,尽管我一直在查看 GC 第 0、1 和 2 代收集的性能计数器。

所以这里的要点是重新使用 HttpClient 不会导致内存泄漏。

关于c# - HttpClient爬取导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14075026/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com