单URLSession与逐请求创建URLSession的性能对比及疑问
你的观察背后的细节
关于「逐请求建会话时系统创建并行连接,最终效果与单会话一致」
你测试的50个请求场景下,系统确实会为每个新建的Session创建独立的TCP连接,但HTTP/1.1协议默认对同一域名的并发连接数有6个的限制。当请求数超过这个阈值时,后续请求会被排队等待可用连接,而单例Session会复用已有的连接池,避免重复创建连接带来的握手开销,同时更合理地控制并发数。
短时间小批量请求下,这种差异可能不明显,但在高并发或持续请求的场景中,多Session的连接池分散会导致:
- 连接数过载,系统被迫频繁创建/销毁连接,增加CPU和内存消耗
- 无法利用HTTP长连接的复用优势,每次请求都要经历TCP三次握手、TLS协商的延迟
关于「DataTask序列化图片比DownloadTask快」
这个现象是正常的,和Session是否单例无关:
URLSessionDataTask直接在内存中处理数据,适合体积较小的图片,省去了磁盘IO的开销URLSessionDownloadTask会先将数据写入临时文件,再读取文件内容,适合大体积文件(比如高清大图),能避免内存占用过高的问题
你可能忽略的关键问题
1. 资源占用与内存风险
每个NSURLSession实例都会创建独立的操作队列、缓存空间、后台线程等资源。频繁创建Session会导致:
- 内存占用持续上升,尤其是如果Session没有被正确调用
invalidateAndCancel或finishTasksAndInvalidate,会出现内存泄漏 - CPU开销增加,系统需要维护多个独立的Session调度逻辑
2. 缓存复用失效
单例Session共享同一个HTTP缓存池,能自动复用符合缓存策略的响应(比如304 Not Modified),减少重复请求的带宽消耗和延迟。而每个新建的Session都有独立的缓存,相同资源的重复请求无法复用缓存,完全是冗余的网络开销。
3. 维护成本飙升
如果后续需要统一调整网络配置(比如全局超时时间、SSL证书验证、代理设置),单例Session只需要修改一处代码即可。而逐请求建Session的模式下,你需要修改所有请求的创建逻辑,维护成本极高,且容易出现遗漏。
4. 后台任务的稳定性
如果你的APP涉及后台下载/上传任务,单例Session的生命周期更可控,系统能更好地调度后台任务。多个独立Session的后台任务容易出现资源竞争,甚至被系统优先回收,导致任务失败。
总结
苹果将「逐请求新建NSURLSession」列为反模式,是从长期运行稳定性、资源高效利用、架构可维护性的角度出发的。短时间小批量测试的性能差异不明显,但在APP的实际使用场景中(持续请求、高并发、后台任务),单例Session的优势会非常显著。建议你还是采用单例Session的模式来统一处理所有网络请求。
内容的提问来源于stack exchange,提问作者Devarshi

