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

Python循环随迭代次数增加变慢,仅执行图片加载关闭操作

问题分析与优化方案

代码复现

from PIL import Image
from tqdm import tqdm

for idx, img in enumerate(tqdm(all_images)):
    image = Image.open(img)
    image.close()

性能下降原因

  1. 内存泄漏触发swap:尽管手动调用了image.close(),但PIL的Image对象底层关联的内存资源可能未被Python垃圾回收器及时回收。随着循环推进,内存占用持续攀升,当物理内存耗尽时系统会启用磁盘交换分区(swap),而磁盘IO速度远低于内存,直接导致迭代速度骤降。
  2. 文件句柄残留:部分场景下image.close()无法完全释放底层文件句柄,累积的句柄会增加系统资源开销,拖慢后续文件操作效率。
  3. 磁盘缓存耗尽:初始阶段系统将高频访问的图像文件缓存到内存,迭代500次后缓存空间不足,后续图像需从磁盘直接读取,速度大幅降低(机械硬盘场景下尤为明显)。

优化方案

1. 用上下文管理器自动释放资源

改用with语句,它会在代码块结束后自动调用close(),且能处理异常场景下的资源释放,比手动调用更可靠:

from PIL import Image
from tqdm import tqdm

for idx, img in enumerate(tqdm(all_images)):
    with Image.open(img) as image:
        # 执行图像处理逻辑
        pass

2. 主动触发垃圾回收

在每次循环后手动调用垃圾回收,及时清理未被回收的内存资源:

import gc
from PIL import Image
from tqdm import tqdm

for idx, img in enumerate(tqdm(all_images)):
    image = Image.open(img)
    image.close()
    gc.collect()

3. 优化文件路径加载方式

如果all_images是加载了所有文件路径的大列表,改用生成器(如glob.iglob代替glob.glob),减少内存占用:

from PIL import Image
from tqdm import tqdm
import glob

# 用生成器分批获取文件路径,而非一次性加载全部
all_images = glob.iglob("/path/to/images/*.jpg")
for idx, img in enumerate(tqdm(all_images)):
    with Image.open(img) as image:
        pass

4. 优化存储与缓存

  • 将图像文件迁移至SSD,提升磁盘读取速度;
  • 若文件数量极大,可分批将图像加载到内存缓存区,减少磁盘IO次数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:05:31