如何使用numpy填充大型数组?创建2^32大小数组进程被终止怎么办?
问题成因
你尝试创建的数组体积超出了系统可用物理内存上限,触发了操作系统的内存不足终止机制(OOM Killer),进程被强制杀死:
- 单个
np.int64类型元素占用8字节,2^32个元素的数组总大小为2^32 * 8B = 32GB,这还不包含numpy生成随机数、数组初始化阶段需要的临时内存开销 - 普通消费级设备通常不具备32GB以上的可用内存,即便是大内存设备如果剩余可用内存不足也会触发该问题,32位操作系统甚至本身就不支持寻址这么大的内存空间
- 你代码里的
sys.setrecursionlimit设置是无效的,当前逻辑没有递归调用,和该报错没有关联。
解决方案
根据你的实际需求选择对应方案即可:
- 如果你不需要这么大规模的数组,直接降低
n的取值即可,比如n=24时数组总大小仅128MB,普通设备完全可以正常运行 - 如果你确实需要处理全量42亿条数据,优先选择分块处理方案,避免全量加载到内存:
- 使用numpy内置的memmap工具,将数组持久化在磁盘上,仅按需加载部分数据到内存操作,示例代码:
# 创建映射到磁盘的数组,不会占用内存 arr = np.memmap('large_array.npy', dtype=np.int64, mode='w+', shape=(2**32,)) # 分块写入随机数,每次处理1000万条,可根据内存大小调整块大小 block_size = 10_000_000 for i in range(0, 2**32, block_size): end = min(i + block_size, 2**32) arr[i:end] = np.random.randint(1, 2**32, size=end - i, dtype=np.int64) # 操作完成后刷入磁盘 arr.flush()- 改用支持外存计算的框架如Dask,它兼容numpy接口,自动完成数据分块、磁盘换入换出逻辑,代码改动极小:
import dask.array as da arr = da.random.randint(1, 2**32, size=2**32, dtype=np.int64) # 后续操作几乎和numpy语法一致,框架自动处理内存调度 - 如果你有大内存服务器资源,确保设备可用物理内存大于36GB(留足临时内存开销)即可直接运行原代码,不建议依赖swap分区运行,会导致执行速度极慢。
内容的提问来源于stack exchange,提问作者Vlad Roshupkin
相关产品推荐
相关产品推荐

