为什么将泡菜文件加载到内存中会占用更多空间?

时间:2018-12-27 08:17:37

标签: python memory pickle

我有一个文件夹,其中包含pickle.dump保存的7603个文件。平均文件大小为6.5MB,因此文件占用的总磁盘空间约为48GB

每个文件都是通过对列表对象进行腌制获得的,列表的结构为

[A * 50] 
 A = [str, int, [92 floats], B * 3] 
                             B = [C * about 6] 
                                  C = [str, int, [92 floats]]

我正在使用的计算机的内存为128GB

但是,我无法通过以下脚本将文件夹中的所有文件加载到内存中:

import pickle
import multiprocessing as mp
import sys
from os.path import join
from os import listdir
import os

def one_loader(the_arg):
    with open(the_arg, 'rb') as source:
        temp_fp = pickle.load(source)
    the_hash = the_arg.split('/')[-1]
    os.system('top -bn 1 | grep buff >> memory_log')
    return (the_hash, temp_fp)

def process_parallel(the_func, the_args):
    pool = mp.Pool(25)
    result = dict(pool.map(the_func, the_args))
    pool.close()
    return result

node_list = sys.argv[-1]
db_path =  db_path
the_hashes = listdir(db_path)
the_files = [join(db_path, item) for item in the_hashes]
fp_dict = {}
fp_dict = process_parallel(one_loader, the_files)

我从脚本中可以看到内存使用情况,内存使用情况是

enter image description here

我对此情节有一些困惑:

  1. 4000个文件占用25GB磁盘空间,但是为什么它们占用的内存却多于100GB

  2. 在内存使用量突然下降之后,我没有收到任何错误,并且可以使用top命令看到脚本仍在运行。但是我完全不知道系统在做什么,其余的内存在哪里。

1 个答案:

答案 0 :(得分:2)

这仅仅是因为序列化数据占用的空间少于运行时管理对象所需的内存空间。

带有字符串的示例:

import pickle

with open("foo","wb") as f:
    pickle.dump("toto",f)

foo在磁盘上(包括pickle标头或其他内容)为14个字节,但在内存中要大得多:

>>> import sys
>>> sys.getsizeof('toto')
53

对于字典,由于哈希表(和其他东西),甚至更糟:

import pickle,os,sys

d = {"foo":"bar"}
with open("foo","wb") as f:
    pickle.dump(d,f)
print(os.path.getsize("foo"))
print(sys.getsizeof(d))

结果:

27
288

所以比率是1到10。

相关问题