Почему загрузка файла консервирования в память займет гораздо больше места? - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть папка, содержащая 7603 файла, сохраненных pickle.dump.Средний размер файла 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 голосов
/ 27 декабря 2018

Это потому, что сериализованные данные занимают меньше места, чем пространство в памяти, необходимое для управления объектом при запуске.

Пример со строкой:

import pickle

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

foo равно 14байт на диске (включая заголовок pickle или что-то еще), но в памяти он намного больше:

>>> 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.

...