#python #memory-management #memory-leaks #garbage-collection #containers
#python #управление памятью #утечки памяти #сбор мусора #контейнеры
Вопрос:
Скрипт Python, который просто загружает файлы 5k из местоположения SFTP и считывает файл и загружает данные в базу данных, на этапе выполнения будет выглядеть следующим образом SFTP-соединение Получает список файлов для обработки, повторяет один за другим a. Загружает один файл b. Читает файл c. Загружает данные в базу данных d. Удалите файл (повторите шаг 3 для всех файлов)
На уровне кода я не вижу утечки памяти. Но мой контейнер завершается с ошибкой памяти. Если я запускаю на своем локальном компьютере и проверяю статистику контейнера, я вижу, что он запрашивает 70 МБ для обработки одного файла (для хранения временных данных и т.д.). Когда он обрабатывает файл 2, он запрашивает еще примерно 70 МБ, не освобождая предыдущую активную память.
Я немного прочитал о Python GC, похоже, в отличие от многих других языков, Python GC не вернет память в ОС, вместо этого она вернется к своему внутреннему распределителю памяти. Есть мысли о том, как преодолеть эту проблему
def batch_load(self):
logging.info("SFTP to DB")
logging.info("SFTP Operations")
files = self.sftp_src_strategy.list_contents()
for file in files:
exec_date = file.split('.')[0][-8:]
execution_date = f'{str(exec_date[:4])}-{str(exec_date[4:6])}-{str(exec_date[6:8])}'
header_row, data = self.sftp_src_strategy.download_data(execution_date, exec_date, file)
logging.info("Sftp Download Success Data extracted from file")
logging.info("DB Operations")
self.db_des_strategy.load_data(execution_date, header_row, data)
logging.info("Data moved to db from SFTP file successfully")
Комментарии:
1. отправьте код, пожалуйста
2. Python не возвращает память операционной системе, но освобождает ее в локальной куче. Теперь он доступен для выделения python. Предполагая, что вы действительно освободили память (не просто закрыли файл, но и удалили все объекты, все еще ссылающиеся на данные), при следующем чтении следует просто снова использовать ту же память. Если вы используете что-то вроде numpy, которое выполняет выделение большого отдельного объекта, могут возникнуть проблемы, когда освобожденная память недостаточно велика и необходимо выделить больше.
3. @tdelaney В таком случае, вы хотите, чтобы я сделал
del my_var
4. ДА. Я предполагаю,
header_row, data
это где твои 70 мегабайт. Поскольку данные первого запуска в этих переменных не удаляются доself.sftp_src_strategy.download_data
перезаписи, у вас есть как старый, так и новый набор данных в памяти одновременно. Либоdel
все в конце каждогоfor
цикла, либо (лучше ИМХО) поместите то, что есть вfor
, в другую функцию. Я напишу ответ.5. Быстрое решение — вернуться к вашей отдельной функции, но использовать ее
multiprocessing
для размещения вProcess
, которая обрабатывает только 1 файл. Или даже просто напишите новый файл .py, который выполняет эту часть работы и принимает параметры из командной строки. Затем используйтеsubprocess
модуль для его запуска.