Есть ли способ избежать удвоения сокола памяти, необходимой в Python? - PullRequest
1 голос
/ 17 января 2020

Я немного новичок в Python, хотя и разбираюсь в solid в других языках программирования. У нас есть набор кода, который использует python, но все равно.

  def on_get(self, req, resp):

      try:

         proc = Popen(["createLotsofData","-p"], stdout=PIPE, stderr=PIPE)
         out_str, err_str = proc.communicate()

         if err_str:
            handle_error(req, resp, "{0} returned '{1}'".format(program, err_str))
            return

         if not out_str:
            handle_error(req, resp, "{0} returned empty file".format(program))
            return

         resp.body = out_str

         resp.status = falcon.HTTP_200

      except Exception as e:
         handle_error(req, resp, "Caught exception " + repr(e))
         return

По сути, у нас есть программа, которая может выводить большое количество информации журнала. Мы говорим выше 600 мег или более.

Проблема в том, что наша система имеет 900 мегабайт оперативной памяти (или на самом деле менее 1,2-1,3 гигабайта). Это вызывает ошибку MemoryError. Итак, после проверки кода, я обнаружил, что когда у меня out_str - строка 600 мегабайт, а затем мы вызываем resp.body = out_str, чтобы дублировать эту память. Это не хорошо.

Я попробовал версию, в которой я отправил вывод Popen в файл, а затем попытался использовать его, хотя для его перемещения в файл требовалось то же количество памяти, что и для метода stdout = PIPE. .

Я пробовал альтернативную версию, используя потоковую природу stdout, такую ​​как

     try:
         proc = Popen(["createLotsofData","-p"], stdout=PIPE, stderr=PIPE)

         resp.content_type = "text/csv"
         resp.stream = proc.stdout
         resp.status = falcon.HTTP_200

      except Exception as e:
         handle_error(req, resp, "Caught exception " + repr(e))
         return

, но даже в этом случае мы все еще видим MemoryError.

Так что, я думаю, я понимаю, что происходит в первом случае, соответственно, телу и телу out_str нужны уникальные копии данных, так что это лишает нас предела памяти. Но почему это происходит со вторым примером? И есть ли способ избежать появления python всплывающей подсказки, и мне нужно в 2 раза больше выходного размера?

...