wutiantong
2018-09-25 17:43:15 +08:00
实际运行环境是新版 MBP,python3.7
```
import collections
import pickle
def make_cnt(section):
cnt = collections.Counter()
for i in range(6000000):
cnt[str(i +6000000*section)] = i
return cnt
if __name__ == '__main__':
cnt0 = make_cnt(0)
pickle.dump(cnt0, open('/tmp/cnt0', 'wb'))
input("Press Enter to continue...")
cnt1 = make_cnt(1)
pickle.dump(cnt1, open('/tmp/cnt1', 'wb'))
input("Press Enter to continue...")
cnt2 = make_cnt(2)
pickle.dump(cnt2, open('/tmp/cnt2', 'wb'))
input("Press Enter to continue...")
cnt3 = make_cnt(3)
pickle.dump(cnt3, open('/tmp/cnt3', 'wb'))
input("Press Enter to continue...")
cnt4 = make_cnt(4)
pickle.dump(cnt4, open('/tmp/cnt4', 'wb'))
input("Press Enter to continue...")
```
这个代码主要是观察 Counter 的内存占用情况,观察结果是:
1. 一个 600 万条的 Counter 占用 900M 内存,平均每条记录占用 150 个字节,5 个这样的 Counter 总计占用内存 4.5G (个人觉得并不算很过分)
2. pickle 序列化后得到的文件是 130 多 M
```
import collections
import pickle
if __name__ == '__main__':
cnt0 = pickle.load(open('/tmp/cnt0', 'rb'))
input("Press Enter to continue...")
cnt1 = pickle.load(open('/tmp/cnt1', 'rb'))
input("Press Enter to continue...")
cnt2 = pickle.load(open('/tmp/cnt2', 'rb'))
input("Press Enter to continue...")
cnt3 = pickle.load(open('/tmp/cnt3', 'rb'))
input("Press Enter to continue...")
cnt4 = pickle.load(open('/tmp/cnt4', 'rb'))
input("Press Enter to continue...")
```
这个代码主要是观察 pickle 反序列化过程中会不会产生额外的内存占用,以及反序列化出来的对象实际大小如何,观察结果是:
1. pickle 的反序列化过程有轻微的内存使用上涨但并不会产生内存泄漏
2. 反序列化出来的 Counter 略小于直接动态生成的 Counter,5 个 Counter 总计占用内存 4.3G
总结一下:
1. pickle 这个库挺不错的,压缩率和运算性能都很可观,而且也没观察到内存爆增或者内存泄漏的情况(至少在我的测试环境下是如此的)
2. 楼主所用的 Counter 每条记录占用 150 字节左右,总计应该是需要 4.5G 左右的内存,6G 内存应该是能撑得住的
3. 我猜楼主在后续的合并操作没有及时回收内存,故而需求了几乎翻倍的内存