Многопроцессорность: struct.error при создании процесса для загрузки большого словаря / json - PullRequest
0 голосов
/ 16 октября 2019

Я пытаюсь загрузить большой объект json в память (как dict), а затем использовать его с networkx для создания графика. Проблема заключается в том, что мне нужно прочитать json, который занимает много памяти, а затем создать объект Graph NetworkX, который сам в основном копирует данные из json / dict при создании экземпляра графа.

После создания графика мне нужно освободить память, занятую json / dict, но я не могу найти способ сделать это.

Я пытался использоватьДиспетчер и процесс из пакета многопроцессорной обработки, но я сталкиваюсь с ошибкой, которая, по моему мнению, вызвана слишком большой вхождением общей памяти.

import multiprocessing
from networkx.readwrite import json_graph
import json

def load_json(state):
    with open("my.json", "r") as f:
        json_data = json.load(f)
    for (k, v) in json_data.items():
        print(k)
        state[k] = v
    print("done")

manager = multiprocessing.Manager()

state = manager.dict()

p = multiprocessing.Process(target=load_json, args=(state,)) 

p.start()

G = json_graph.node_link_graph(state)

Если это выполнится успешно, я ожидаю вызова p.join() для освобождения памяти из json.

Функция node_link_graph берет словарь и выполняет итерацию по нему для создания экземпляра графа networkx. Однако, когда я вызываю эту функцию, я получаю KeyError, в которой говорится, что «ссылки» отсутствуют («ссылки» - это последний ключ в объекте json и содержит ребра графа).

Затем я получаю эту ошибку:

Process Process-2:
Traceback (most recent call last):
  File "/automnt/toolbox/users/USER/anaconda3/envs/ENV/lib/python3.6/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/automnt/toolbox/users/USER/anaconda3/envs/ENV/lib/python3.6/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "<ipython-input-4-7d59757efe1b>", line 6, in load_json
    state[k] = v
  File "<string>", line 2, in __setitem__
  File "/automnt/toolbox/users/USER/anaconda3/envs/ENV/lib/python3.6/multiprocessing/managers.py", line 756, in _callmethod
    conn.send((self._id, methodname, args, kwds))
  File "/automnt/toolbox/users/USER/anaconda3/envs/ENV/lib/python3.6/multiprocessing/connection.py", line 206, in send
    self._send_bytes(_ForkingPickler.dumps(obj))
  File "/automnt/toolbox/users/USER/anaconda3/envs/ENV/lib/python3.6/multiprocessing/connection.py", line 393, in _send_bytes
    header = struct.pack("!i", n)
struct.error: 'i' format requires -2147483648 <= number <= 2147483647

У меня достаточно памяти для загрузки графика json и создания из него экземпляра графика, но потом я больше ничего не могу сделать, потому что больше нет памяти, поэтому мне нужно освободитьТеперь бесполезное распределение памяти JSON.

Я вижу, что подпроцесс загружает до 50 ГБ памяти сверху. Я могу вызвать state.keys () и вижу, что ключ "links" действительно отсутствует. Мне интересно, если я использую ограничение размера памяти, которое может иметь подпроцесс, и если да, то что я могу сделать, чтобы обойти его. Или другой способ очистки памяти, выделенной для json после создания графика.

...