Python 3.7中不await asyncio任务致内存泄漏,求标准解决方法
解决方案
修正后的代码实现
首先调整任务创建和结果存储的逻辑,避免不必要的引用残留:
# 程序启动初期(类的初始化或启动方法内) self.slow_task = asyncio.create_task(self._fetch_slow_value()) self._slow_value = None # 预先初始化结果存储变量
实现异步获取慢值的内部方法:
async def _fetch_slow_value(self): # 直接返回慢函数结果,不直接赋值给实例属性 return await slow_function()
后续需要使用值时,通过以下方法获取:
async def get_slow_value(self): if self._slow_value is None: # 等待任务完成并获取结果 self._slow_value = await self.slow_task # 任务完成后删除对Task对象的引用,帮助垃圾回收 del self.slow_task return self._slow_value
为什么能解决内存泄漏?
- 原代码中可能因意外保留了协程(coroutine)或未完成Task的引用,导致相关对象无法被垃圾回收。
- 修正后,任务完成后主动删除
self.slow_task的引用,Task对象失去所有外部引用,就能被GC正常回收。
Python 3.7 注意事项
asyncio.create_task()是3.7+的标准方法,用来创建Task对象(替代旧版的ensure_future()),使用它能正确管理异步任务生命周期。- 原代码中
slow_function_wrapper作为实例方法,调用时必须传入self,否则会触发参数错误,这也是原代码的隐性问题。
另一种可选实现:用Future手动管理
如果需要更精细的控制,可以用asyncio.Future包装结果(Task本质是Future的子类,逻辑一致):
self.slow_future = asyncio.Future() asyncio.create_task(self._set_future_result(self.slow_future)) async def _set_future_result(self, future): result = await slow_function() future.set_result(result) async def get_slow_value(self): if not self.slow_future.done(): await self.slow_future result = self.slow_future.result() # 清除对Future的引用 del self.slow_future return result
内容的提问来源于stack exchange,提问作者Shtut
相关产品推荐
相关产品推荐

