Занятая питоном память продолжает накапливаться, когда запускается через службу и не освобождается в ОС (торнадо) - PullRequest
0 голосов
/ 30 сентября 2019

Мы использовали диспетчер задач Windows для мониторинга заполнения памяти. Первоначально, после запуска службы, потребляемая память составляет «12,0 МБ». Когда мы нажимаем http GET-запрос для «http://localhost:8888/abc" в точке 2 (указан в коде выше), память переходит к 30 МБ. По мере перехода кода к точке 3 потребление памяти увеличивается до 31 МБ. После пункта 3, согласно нашему наблюдению,память никогда не выключается и остается на уровне 31 МБ. Поскольку мы вызываем HTTP-запрос GET несколько раз, это потребление памяти увеличивается при каждом запросе до 32 МБ, 33 МБ и т. д., и оно никогда не уменьшается. Мы пытались использовать «del emr_client», используя del метод для удаления объекта emr_Client, но, похоже, ничего не работает. В нашей большой базе кода эта накопленная память приводит к тому, что наш веб-сервер переходит в неработоспособное состояние, и у нас есть только один вариант - остановить и запустить службу. Такое же поведение существуети для Linux-машины.

Мы понимаем, что python сохраняет импортированный пакет в памяти для более быстрого выполнения последующих вызовов, но по любой причине память не освобождается после окончания срока службы объекта (например, emr_client в приведенном выше примере). после того, как его объем завершен.

import tornado.ioloop
import tornado.web
from tornado.httpserver import HTTPServer

class BotoContainer:
    def __init__(self):
        import boto3 # 2
        emr_client = boto3.client("emr", **{'region_name': 'us-east-1',
                                        'aws_access_key_id': 'XXXXXXX',
                                        'aws_secret_access_key': 'XXXXXXX',
                                        'aws_session_token': 'XXXXXXX'})
        print emr_client # 3


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        BotoContainer()


class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
        (r"/abc", MainHandler)
    ]

        tornado.web.Application.__init__(self, handlers)


if __name__ == "__main__":
    app = HTTPServer(Application())
    app.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
...