7

redisのpubsubを使用してイベントを配信するために、 tornado-redis(基本的にはadispではなくtornado.genインターフェイスで動作するようにわずかに変更されたbrükvaのフォーク)を使用しようとしています。

そこで、この例に触発されてテストするための小さなスクリプトを書き留めました。

import os

from tornado import ioloop, gen
import tornadoredis


print os.getpid()

def on_message(msg):
    print msg

@gen.engine
def listen():
    c = tornadoredis.Client()
    c.connect()
    yield gen.Task(c.subscribe, 'channel')
    c.listen(on_message)

listen()

ioloop.IOLoop.instance().start()

残念ながら、私PUBLISHredis-cliメモリ使用量を調べている間、増加し続けました。

メモリ使用量をプロファイリングするために、私は最初にguppy -peを使用しようとしましたが、python 2.7では機能しませんでした(はい、トランクを試しても)ので、pymplerにフォールバックしました。

import os

from pympler import tracker
from tornado import ioloop, gen
import tornadoredis


print os.getpid()

class MessageHandler(object):

    def __init__(self):
        self.memory_tracker = tracker.SummaryTracker()

    def on_message(self, msg):
        self.memory_tracker.print_diff()

@gen.engine
def listen():
    c = tornadoredis.Client()
    c.connect()
    yield gen.Task(c.subscribe, 'channel')
    c.listen(MessageHandler().on_message)

listen()

ioloop.IOLoop.instance().start()

これで、編集するたびにPUBLISH、一部のオブジェクトがリリースされなかったことがわかりました。

                                            types |   # objects |   total size
===================================================== | =========== | ============
                                                 dict |          32 |     14.75 KB
                                                tuple |          41 |      3.66 KB
                                                  set |           8 |      1.81 KB
                                       instancemethod |          16 |      1.25 KB
                                                 cell |          22 |      1.20 KB
                          function (handle_exception) |           8 |    960     B
                                     function (inner) |           7 |    840     B
                                            generator |           8 |    640     B
                             <class 'tornado.gen.Task |           8 |    512     B
                           <class 'tornado.gen.Runner |           8 |    512     B
  <class 'tornado.stack_context.ExceptionStackContext |           8 |    512     B
                                                 list |           3 |    504     B
                                                  str |           7 |    353     B
                                                  int |           7 |    168     B
                           builtin_function_or_method |           2 |    144     B
                                                types |   # objects |   total size
===================================================== | =========== | ============
                                                 dict |          32 |     14.75 KB
                                                tuple |          42 |      4.23 KB
                                                  set |           8 |      1.81 KB
                                                 cell |          24 |      1.31 KB
                                       instancemethod |          16 |      1.25 KB
                          function (handle_exception) |           8 |    960     B
                                     function (inner) |           8 |    960     B
                                            generator |           8 |    640     B
                             <class 'tornado.gen.Task |           8 |    512     B
                           <class 'tornado.gen.Runner |           8 |    512     B
  <class 'tornado.stack_context.ExceptionStackContext |           8 |    512     B
                                               object |           8 |    128     B
                                                  str |           2 |    116     B
                                                  int |           1 |     24     B
                                                types |   # objects |   total size
===================================================== | =========== | ============
                                                 dict |          32 |     14.75 KB
                                                tuple |          42 |      4.73 KB
                                                  set |           8 |      1.81 KB
                                                 cell |          24 |      1.31 KB
                                       instancemethod |          16 |      1.25 KB
                          function (handle_exception) |           8 |    960     B
                                     function (inner) |           8 |    960     B
                                            generator |           8 |    640     B
                             <class 'tornado.gen.Task |           8 |    512     B
                           <class 'tornado.gen.Runner |           8 |    512     B
  <class 'tornado.stack_context.ExceptionStackContext |           8 |    512     B
                                                 list |           0 |    240     B
                                               object |           8 |    128     B
                                                  int |          -1 |    -24     B
                                                  str |           0 |    -34     B

実際にメモリリークがあることがわかったので、これらのオブジェクトが作成された場所を追跡するにはどうすればよいですか?私はここから始めるべきだと思いますか?

4

1 に答える 1

4

Tornado をバージョン 2.3 にアップグレードすると、この問題が修正されます。

ExceptionStackContext が非常に迅速にリークするという同じ問題が発生していました。これは、このバグ レポート: https://github.com/facebook/tornado/issues/507に関連しており、このコミットで修正されました: https://github.com/facebook/tornado/commit/57a3f83fc6b6fa4d9c207dc078a337260863ff99。2.3 にアップグレードすることで、問題は解決しました。

于 2012-06-02T16:45:52.700 に答える