7

我一直在尝试使用tornado-redis(它基本上是brükva的一个分支,经过稍微修改后可以使用 tornado.gen 接口而不是 adisp),以便通过使用redis 的 pubsub来传递事件。

所以我写了一个小脚本来测试这个例子的启发。

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()

不幸的是,当我PUBLISH编辑通过redis-cli内存使用不断上升。

为了分析内存使用情况,我首先尝试使用guppy-pe但它在 python 2.7 下不起作用(是的,甚至尝试过trunk)所以我回到了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 回答