Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Web
  • » Tornadio2. Memory leak. Лишние ссылки на объект. [RSS Feed]

#1 Авг. 10, 2012 07:26:09

evil_rabbit
Зарегистрирован: 2012-07-26
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Tornadio2. Memory leak. Лишние ссылки на объект.

Здравствуйте. Пишу сервер с использованием Tornado+Tornadio2.
Когда подключается юзер через веб-сокеты, то управление передаётся обработчику UserHandler, вызывается метод on_open и т.д.
При закрытии соединения вызывается on_close().
В общем всё, как в хелло-ворлдах.
через sys.getrefcount я выяснил, что на обработчик есть 3+ ссылок.

class UserHandler(SocketConnection):
  def __del__(self):
    print 'user instance deleted'
  def on_open(self, request):
    print 'user connected'
    # то, что дальше запросто выпиливается, но количество ссылок на объект не уменьшается
  def on_close(self):
    print 'user disconnected'
Вопрос: как убить объект обработчика после завершения on_close(), чтобы он мне всё-таки написал “user instance deleted”?

Отредактировано evil_rabbit (Авг. 10, 2012 07:28:15)

Офлайн

#2 Авг. 10, 2012 10:58:12

Sleepwalker
От:
Зарегистрирован: 2008-07-18
Сообщения: 68
Репутация: +  0  -
Профиль   Отправить e-mail  

Tornadio2. Memory leak. Лишние ссылки на объект.

SocketConnection ссылается на обьект Session посредством self.session.
В свою очередь Session ссылается на SocketConnection посредством self.conn.
Выходят такие себе цыклические ссылки. Но это не значит что они не обрабатываются сборщиком мусора:
Вот вырезка из документации по __del__

Circular references which are garbage are detected when the option cycle detector is enabled (it's on by default), but can only be cleaned up if there are no Python-level __del__() methods involved.

Т.е. хоть там и есть цыклические ссылки, они должны нормально утилизироватся, при условии что вы не будете там определять метод __del__.

Но это мое предположение, нужно будет поинвестигейтить.



Офлайн

#3 Авг. 10, 2012 14:59:03

evil_rabbit
Зарегистрирован: 2012-07-26
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Tornadio2. Memory leak. Лишние ссылки на объект.

Ну вот у меня как раз был определён __del__()
Гонял тесты в 4 потока каждые 1,5 секунды создавал новое подключение (примерно через 40 секунд они отваливались по таймауту). Потребление памяти росло примерно на метр каждые 2 минуты.
Сделал del gc.garbage по рандому в on_open, вроде, держится стабильно. Но это пока не окончательный вариант сервера и от костыля хотелось бы избавиться.
В понедельник выпилю __del__() попробую без него.

Офлайн

#4 Авг. 22, 2012 11:54:22

evil_rabbit
Зарегистрирован: 2012-07-26
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Tornadio2. Memory leak. Лишние ссылки на объект.

Сделал без __del__(). Всё равно течет, но это уже не важно.
Сейчас больше интересует другое. У меня в UserHandler есть метод subscribe(), он создаёт подключение к Redis и начинает его слушать

    @tornado.gen.engine
    def subscribe(self, channel, listener=None):
        if (channel in self.subscriptions and self.subscriptions[channel] != None) \
        or len(self.subscriptions)>=self.subscriptions_limit:
            print self.subscriptions
            raise SubscribeException
        redis = redis_pool.get()
        yield tornado.gen.Task(
            redis.subscribe,
            channel
        )
        if listener == None:
            redis.listen(self.common_listener)
        else:
            redis.listen(listener)
        self.subscriptions[channel] = redis
Т.е. клиент подписывается на какой-то канал (уведомления, чат и т.п.). Всё бы ничего, но внезапно, когда зашел со второго браузера, я обнаружил, что self.subscription используется всеми подключенными клиентами сразу, т.е. один подписался, другие уже не могут (дамп self.subscriptions перед порождением исключения). Почему такое происходит? Разве на каждое подключение не создаётся отдельный объект UserHandler со своими переменными?

UPD
Разобрался. Написал в on_open()
self.subscriptions = {}
А из самого класса убрал. Пойду учить матчасть.

Отредактировано evil_rabbit (Авг. 26, 2012 05:57:11)

Офлайн

  • Начало
  • » Web
  • » Tornadio2. Memory leak. Лишние ссылки на объект.[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version