迭代Python大列表时如何释放内存?
Python大型列表遍历中释放内存的问题
我有一个大型列表my_list,加载到内存中会占用数GB空间。我需要遍历该列表,且每个元素仅使用一次,因此希望在遍历后删除元素释放内存——遍历过程中我还要在内存中存储其他内容,所以my_list占用的内存必须被释放。
我知道生成器是多数场景下的最优选择,比如将列表转存为CSV文件后逐行读取,这样my_list根本不会被加载到内存中。但本次仅作讨论,不采用这种方案。
尝试过的无效方法
- 使用
pop()删除元素,内存占用无变化:
>>> my_list = [1,2,3] >>> sys.getsizeof(my_list) 80 >>> my_list.pop() >>> sys.getsizeof(my_list) 80
- 使用
del删除最后一个元素,同样无法释放内存:
>>> my_list = [1,2,3] >>> sys.getsizeof(my_list) 80 >>> del my_list[-1] >>> sys.getsizeof(my_list) 80
即使显式调用gc.collect(),也没有效果。
找到的可行但有缺陷的方法
复制数组可以让内存占用降低,但复制过程会占用双倍内存,这带来了新的问题:
>>> my_list = [1,2,3] >>> sys.getsizeof(my_list) 80 >>> my_list.pop() >>> my_list_copy = my_list.copy() >>> sys.getsizeof(my_list_copy) 72
目前找不到相关资料说明这种方法是否不可行或属于不良实践。如果不能采用这种方式,最佳替代方案是什么?继续用生成器读取CSV?还是有更好的方法?
补充:垃圾回收器对超大列表的作用
正如@Scott Hunter指出,垃圾回收器对超大列表有效:
>>> my_list = [1] * 10**9 >>> for i in range(10): ... for j in range(10**8): ... del my_list[-1] ... gc.collect() ... print(sys.getsizeof(my_list))
输出结果:
8000000056 8000000056 8000000056 8000000056 8000000056 4500000088 4500000088 2531250112 1423828240 56
内容的提问来源于stack exchange,提问作者Nik
相关产品推荐
相关产品推荐

