Django-background-task执行完成后如何释放内存资源?
Django-background-tasks 内存无法释放解决方案
核心问题根因
django-background-tasks 默认采用常驻单进程/多进程模式执行任务,Python 进程的内存管理机制为:仅回收进程内部未使用的内存供自身复用,不会主动将空闲内存返还给操作系统,只有进程退出时才会释放所有持有的内存。因此多轮大内存任务执行后,进程内存占用会持续上涨,直到进程重启才会回落。
可落地方案
1. 代码层内存优化(适配现有项目结构)
直接修改现有业务代码降低内存占用峰值,同时提升GC回收效率:
- ORM 查询分块加载:不要全量加载 QuerySet 到内存,使用
iterator()分批次拉取数据 - 大对象用完主动删除,手动触发垃圾回收
- 所有大内存变量使用局部变量,避免全局缓存持有引用
修改后的代码示例:
file_handler.py
import gc def process_data_n_download(queryset_object): """处理该ORM对象用于生成文件""" # 单批次加载200条数据到内存,可根据实际场景调整chunk_size for item in queryset_object.iterator(chunk_size=200): # 单条数据处理逻辑 single_file_generate(item) # 处理完立刻删除临时对象,释放引用 del item # 全量处理完成后主动触发垃圾回收 gc.collect()
tasks.py
# 给大内存任务单独指定队列,方便后续单独分配worker资源 @background(queue='large_mem_tasks', remove_existing_tasks=True) def my_task(): """ 长耗时任务,执行时长20-30分钟,包含部分数据库交互操作 """ process_data_n_download(model_queryset_object)
2. 任务执行架构调整(根源解决内存堆积问题)
调整worker启动参数,让每个大内存任务执行完就销毁对应进程,自动释放所有内存:
启动worker时添加 --max-tasks-per-child 1 参数,指定每个子进程跑完1个任务就自动退出,主进程会自动拉起新的子进程处理后续任务,完全避免内存堆积。
启动命令示例:
# 单独启动大内存任务队列的worker,2个并发进程,每个进程跑1个任务就销毁 python manage.py process_tasks --queue large_mem_tasks --processes 2 --max-tasks-per-child 1
其中 --processes 参数根据你的可用内存配额调整,比如单任务占1G、总可用内存3G,可以设置为2,预留1G给系统和主进程使用。
3. K8s环境兜底方案
针对你当前的Daemon Pod部署模式,新增Pod内存使用率探针,当内存使用率超过阈值(比如85%)时自动触发Pod滚动重启,作为极端场景下的兜底保障。
内容的提问来源于stack exchange,提问作者Akash Pagar
相关产品推荐
相关产品推荐

