我如何追踪/修复龙卷风中的内存泄漏
我一直在尝试使用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()
不幸的是,正如我通过redis-cli
PUBLISH
内存使用量持续上升。
为了剖析内存使用情况,我首先尝试使用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
现在我知道确实存在内存泄漏,我如何跟踪这些对象的创建位置? 我想我应该从这里开始?
将Tornado升级到版本2.3应该可以解决这个问题。
我遇到了ExceptionStackContext很快泄漏的问题。 它与这个错误报告有关:https://github.com/facebook/tornado/issues/507并在此提交中修复:https://github.com/facebook/tornado/commit/57a3f83fc6b6fa4d9c207dc078a337260863ff99。 升级到2.3为我解决了这个问题。
链接地址: http://www.djcxy.com/p/59185.html