Исключение памяти при запуске контейнера, который выполняет скрипт Python, но я не видел утечки памяти

#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 модуль для его запуска.