You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#使用HttpClient多并发HttpGet请求后内存未释放问题

内存未释放的常见原因(针对你的C#并发HTTP扫描场景)

1. HttpClient实例滥用

如果每次请求都新建HttpClient实例,会导致底层HttpMessageHandler和套接字资源无法及时回收。默认HttpClient的HttpMessageHandler自带连接池,频繁创建实例会造成资源泄漏,累积大量未释放的句柄和内存。正确做法是复用单例HttpClient,或者用IHttpClientFactory管理实例生命周期。

2. 异步任务管理不当

  • 并发请求如果没配置CancellationToken,或者任务未被正确等待/终止,可能导致任务实例和关联资源长期驻留内存。比如用Task.WhenAll却未处理异常,部分任务处于挂起状态,GC无法回收这些任务对象。
  • 若使用async void方法,未捕获的异常会导致线程池资源泄漏,同时任务状态无法被正确清理。

3. 大对象堆(LOH)碎片

批量请求返回的响应内容(即使仅状态码,也可能包含响应头、缓存数据)若为超过85KB的大对象,会被分配到LOH。LOH回收频率低且不会压缩,多次扫描后会产生碎片,导致内存无法有效复用,表现为内存持续占用。比如缓存了每个请求的响应内容,或未及时丢弃响应流,都会累积大量LOH对象。

4. 静态/全局集合未清理

如果用静态列表、字典存储扫描结果,每次扫描后未清空这些集合,或集合内对象被其他全局引用持有,GC无法回收这些对象。比如静态变量List<ScanResult>每次扫描都追加数据却不清理,内存自然持续增长。

5. HTTP资源未释放

手动处理HttpWebRequest或HttpResponseMessage时,若未用using语句包裹或调用Dispose(),会导致响应流、连接资源无法释放。比如获取HttpResponseMessage后,未释放Content或整个响应对象,这些资源会被持续持有。
错误示例:

var response = client.GetAsync(url).Result;
// 未调用 response.Dispose()

正确示例:

using var response = await client.GetAsync(url);

6. GC回收时机偏差

有时内存占用高不一定是泄漏,可能是GC尚未触发回收。但多次扫描后内存持续上涨且不回落,大概率是泄漏。可在扫描完成后手动调用GC.Collect()测试,若内存仍未下降,说明存在未释放的资源。另外,.NET内存回收分代,老年代对象若被引用,会长期占用内存。

内容的提问来源于stack exchange,提问作者devLander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 22:13:22