numpy.load(mmap_mode='r')仅VSCode SSH终端正常,其他终端报文件打开过多错误
解决
numpy.load内存映射时OSError: [Errno 24] Too many open files的终端差异问题 核心原因
不同SSH终端的进程文件描述符上限默认设置不同。VSCode的集成终端在启动时可能自动调整了ulimit值,而Termius、MobaXterm、Windows Terminal等终端继承的是SSH会话的默认限制——当你用mmap_mode='r'加载大量.npy文件时,每个内存映射都会占用一个文件描述符,一旦数量超过上限就会触发报错。
解决方案
1. 临时提升当前终端的文件描述符上限
在运行Python脚本前,先执行命令调整上限(数值可根据你的文件数量调整,比如设为4096):
ulimit -n 4096
执行后再运行脚本即可,注意这个设置仅对当前终端会话有效,关闭终端后会恢复默认值。
2. 永久修改系统级文件描述符上限
如果需要长期生效,可修改系统配置:
- 编辑
/etc/security/limits.conf文件,添加两行(替换your_username为你的实际用户名):your_username soft nofile 4096 your_username hard nofile 8192 - 编辑
/etc/pam.d/common-session,确保存在以下配置:session required pam_limits.so - 重启SSH服务或重新登录终端,设置即可生效。
3. 优化代码:减少同时打开的文件描述符
如果加载的文件数量确实过大,除了调整上限,还可以优化代码逻辑:
- 避免一次性加载所有内存映射对象到列表,改为按需加载、使用后立即关闭。内存映射对象可调用
.close()方法释放文件描述符,也可以用with语句自动管理:# 示例:按需处理单个文件 for path in data_paths: with np.load(path, mmap_mode='r') as data_map: # 此处编写处理data_map的逻辑 process_data(data_map) # 离开with块后自动关闭映射,释放文件描述符 - 如果必须保留部分映射对象,定期清理不再使用的实例,调用
del并触发垃圾回收:import gc # 清理指定索引的映射对象 del self.data_memmaps[old_indices] gc.collect()
验证方法
在不同终端中执行ulimit -n命令,对比输出数值——你会发现VSCode终端的文件描述符上限明显高于其他终端,这就是为什么只有它能正常运行脚本的原因。
内容的提问来源于stack exchange,提问作者reopio
相关产品推荐
相关产品推荐

