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

Linux环境下Python脚本内存未释放问题求助

排查Linux环境下Python多进程PDF处理脚本的内存泄漏问题

问题背景

编写了一个Python脚本,核心流程如下:

  1. 读取包含PDF文件URL的CSV文件,输入格式示例:
Bid Number,Items
45455454,['https://example.com/file1.pdf']
230000000237,"['https://example.com/file2.pdf', 'https://example.com/file3.pdf']"
  1. 通过ProcessPoolExecutor创建50个进程,每个进程为单个标的的URL创建线程(单标的URL数量不超过10个),完成PDF下载、分析后,将结果写入新CSV文件。

异常现象:M1 Mac开发环境中内存无线性增长,运行稳定;但生产环境Linux机器内存持续线性增长,最终耗尽导致进程/线程运行失败。两台机器使用相同的Python 3.10版本及依赖库:

certifi==2023.11.17
cffi==1.16.0
charset-normalizer==3.3.2
cryptography==41.0.7
idna==3.6
numpy==1.26.2
pandas==2.1.4
pycparser==2.21
PyMuPDF==1.23.8
PyMuPDFb==1.23.7
python-dateutil==2.8.2
pytz==2023.3.post1
requests==2.31.0
six==1.16.0
tqdm==4.66.1
tzdata==2023.3
urllib3==2.1.0

排查与解决思路

1. 强制释放PyMuPDF资源

PyMuPDF(fitz)的C扩展对象在Linux下内存回收效率低于Mac,若未显式释放易累积内存:

  • 处理完PDF后,必须调用doc.close(),并手动删除对象触发垃圾回收:
    doc = fitz.open("temp.pdf")
    # 执行PDF分析逻辑
    doc.close()
    del doc
    import gc
    gc.collect()
    
  • 避免在循环/线程中重复创建fitz对象却不释放,Linux不会主动回收未释放的C扩展内存。

2. 优化进程池资源复用

ProcessPoolExecutor长期复用进程可能累积未清理资源:

  • 降低进程数量:将max_workers设为CPU核心数的1-2倍(而非固定50),减少内存占用基数。
  • 启用进程自动重启:设置maxtasksperchild参数,让每个进程处理N个任务后自动退出重启,避免资源累积:
    from concurrent.futures import ProcessPoolExecutor
    with ProcessPoolExecutor(max_workers=8, maxtasksperchild=10) as executor:
        # 提交处理任务
    

3. 线程级资源清理

每个进程内的线程需确保资源及时释放:

  • requests下载PDF后,用上下文管理器或显式关闭响应对象:
    # 推荐用法:上下文管理器自动关闭响应
    with requests.get(url) as response:
        with open("temp.pdf", "wb") as f:
            f.write(response.content)
    
  • 处理完成后立即删除临时PDF文件,避免磁盘文件占用导致内存缓存增长:
    import os
    os.remove("temp.pdf")
    

4. 定位泄漏点

在Linux环境下用工具精准定位内存泄漏来源:

  • 用top或ps aux跟踪单个进程的内存变化,确认是所有进程都增长还是特定进程异常。
  • 在脚本中嵌入tracemalloc监控内存分配:
    import tracemalloc
    tracemalloc.start()
    # 执行一段任务后
    snapshot = tracemalloc.take_snapshot()
    top_stats = snapshot.statistics('lineno')
    # 打印内存占用Top10的代码行
    for stat in top_stats[:10]:
        print(stat)
    
  • 用objgraph排查对象引用链,找出未被回收的大对象(如PDF文档、响应对象)。

5. 适配Linux内存管理策略

Mac的内存压缩、页缓存自动回收机制可能掩盖泄漏,Linux内存回收更保守:

  • 检查vm.swappiness参数,若值过低(默认60),系统会优先使用物理内存,可适当调高让系统更早使用交换分区。
  • 确保Linux系统配置了足够的交换空间,避免内存耗尽直接崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 02:23:19