У меня есть некоторые json файлы с 500 МБ. Если я буду использовать "тривиальный" json.load для загрузки его содержания внезапно, то он использует большую память.
Существует ли способ считать частично файл? Если бы это был текст, строка разграничила файл, я смог бы выполнить итерации по строкам. Я ищу аналогию с ним.
Какие-либо предложения?Спасибо
Краткий ответ: нет.
Чтобы правильно разделить файл json, нужно хорошо знать граф объектов json.
Однако, если у вас есть эти знания, вы можете реализовать файловый объект, который обертывает файл json и выделяет нужные фрагменты.
Например, если вы знаете, что ваш файл json представляет собой единственный массив объектов, вы можете создать генератор, который обертывает файл json и возвращает фрагменты массива.
Чтобы правильно разбить json-файл, вам нужно будет выполнить синтаксический анализ содержимого строки.
Я не знаю, что генерирует ваш json-контент. Если возможно, я бы подумал о создании нескольких управляемых файлов вместо одного огромного файла.
По поводу вашего упоминания о нехватке памяти я должен спросить, действительно ли вы управляете памятью. Используете ли вы ключевое слово "del" для удаления старого объекта перед попыткой чтения нового? Python никогда не должен молча сохранять что-то в памяти, если вы его удалили.
в дополнение к @codeape
Я бы попытался написать собственный парсер json, который поможет вам понять структуру большого двоичного объекта JSON, с которым вы имеете дело. Распечатайте только названия ключей и т. Д. Создайте иерархическое дерево и решите (сами), как вы можете его разбить. Таким образом, вы можете делать то, что предлагает @codeape - разбивать файл на более мелкие части и т. Д.
Другая идея - попробовать загрузить его в базу данных хранилища документов, такую как MongoDB. Он хорошо справляется с большими двоичными объектами JSON. Хотя вы можете столкнуться с той же проблемой при загрузке JSON - избегайте проблемы, загружая файлы по одному.
Если путь вам подходит, то вы можете взаимодействовать с данными JSON через их клиента и, возможно, вам не придется хранить весь большой двоичный объект в памяти
Таким образом, проблема не в том, что каждый файл слишком большой, а в том, что их слишком много, и они, кажется, складываются в памяти. Сборщик мусора Python должен быть в порядке, если вы не храните ссылки, которые вам не нужны. Трудно точно сказать, что происходит без какой-либо дополнительной информации, но некоторые вещи вы можете попробовать:
Модульный код. Сделайте что-то вроде:
для json_file в list_of_files:
process_file(json_file)
Если вы напишете process_file()
таким образом, что он не будет полагаться на какое-либо глобальное состояние и не будет
изменить любое глобальное состояние, сборщик мусора должен уметь выполнять свою работу.
Обрабатывайте каждый файл в отдельном процессе. Вместо синтаксического анализа всех JSON-файлов сразу, напишите
программа, которая анализирует только один и передает каждый из них из сценария оболочки или из другого python
процесс, вызывающий скрипт через подпроцесс .. Попен
. Это немного менее элегантно, но если
больше ничего не работает,Это гарантирует, что вы не будете удерживать устаревшие данные из одного файла в
следующий.
Надеюсь, это поможет.
«сборщик мусора должен освободить память»
Верно.
Поскольку это не так, значит, что-то еще не так. Как правило, проблема с бесконечным ростом памяти - это глобальные переменные.
Удалить все глобальные переменные.
Превратите весь код уровня модуля в более мелкие функции.