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

为什么循环中使用with as配合np.load读取文件时内存未被释放?

内存上涨原因
  • numpy数组视图持有原始内存引用:你从np.load返回的dataset中取出的x_batch、y_batch本质是整个加载进内存的npz文件数据块的视图,你后续追加到data_list中的x_batch[i]也是基于x_batch的子视图,只要这些子视图没有被销毁,整个原始大数组的内存就会被持有无法释放,哪怕你已经退出了with代码块。
  • 对with...as...语法的作用理解有误:该语法仅保证在退出作用域时自动关闭关联的资源(此处是npz文件的IO句柄),不会自动删除作用域内的变量、也不会强制回收变量占用的内存,只要变量还被其他对象引用,Python的垃圾回收机制就不会释放对应的内存空间。
  • 筛选后数据总大小超出预期:如果INDICES覆盖的类别较多,最终筛选后存入data_list的样本总大小本身超过内存上限,也会导致内存持续上涨。
解决思路
  • 存储样本时强制生成拷贝:将追加数据的代码改为data_list.append((y_batch[i], x_batch[i].copy())),主动切断单样本和原始大数组的引用关系,原始大数组在with块退出后没有其他引用就会被自动回收。
  • 主动清理临时变量并触发垃圾回收:在每轮循环的with块结束后,新增代码删除临时变量并手动触发垃圾回收:
    del x_batch, y_batch, dataset
    import gc
    gc.collect()
    
  • 使用内存映射加载文件:调用np.load时添加mmap_mode='r'参数,即np.load(path, mmap_mode='r'),通过内存映射的方式加载文件,数组数据默认存放在磁盘中,仅访问到的部分会加载到内存,可大幅降低峰值内存占用。
  • 筛选结果直接落盘不存内存:如果筛选后的总样本量确实超过内存上限,不要把所有结果都存在data_list中,改为边筛选边写入磁盘,比如存储为HDF5格式或者分块的npz文件,后续处理时按需读取即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:27:05