Python使用aiohttp ClientSession并发请求时是否存在内存泄漏?
问题解答
是否属于内存泄漏
分两种场景判断:
- 正常网络环境下,
_RequestContextManager实例分配数增长到峰值后保持稳定:不属于内存泄漏。这是aiohttp ClientSession默认的连接池复用机制导致的,客户端会缓存一定数量的可用连接和关联的上下文对象,达到连接池数量上限后就不会再新增分配,属于正常的性能优化设计。 - 网络故障触发请求失败后,实例分配数持续上涨且网络恢复后不会回落:属于内存泄漏,这是aiohttp旧版本的已知bug,异常场景下(超时、连接拒绝等)请求上下文的引用没有被正确释放,未完成的请求关联对象被事件循环或异常栈持有,无法被垃圾回收,最终导致实例持续堆积。
可行的解决办法
- 优先升级aiohttp到3.8.4及以上正式版本,该类异常场景下的内存泄漏问题已经在后续版本的bug修复中被覆盖,官方补全了异常分支的引用清理逻辑,升级后即可解决。
- 若受环境限制无法升级版本,可采用以下临时方案规避:
- 放弃全局共享ClientSession,改为在
do_request函数内部创建临时ClientSession,请求执行完成后立刻执行await session.close()主动销毁会话,适合请求量不大、可以牺牲部分连接池复用性能的场景。 - 给
asyncio.gather添加return_exceptions=True参数,同时在do_request的异常捕获分支末尾,手动del删除response等局部变量,主动触发垃圾回收清理残留引用。
- 放弃全局共享ClientSession,改为在
- 可选优化:初始化ClientSession时主动限制连接池大小,例如添加
connector=aiohttp.TCPConnector(limit=20)参数,避免连接池缓存过多对象占用不必要的内存。
内容的提问来源于stack exchange,提问作者Grant
相关产品推荐
相关产品推荐

