7

簡略化した形式で次のようなコードがあります。

from tornado import gen, httpclient, ioloop

io_loop = ioloop.IOLoop.instance()
client = httpclient.AsyncHTTPClient(io_loop=io_loop)

@gen.engine
def go_for_it():
    while True:
        r = yield gen.Task(fetch)

@gen.engine
def fetch(callback):
    response = yield gen.Task(client.fetch, 'http://localhost:8888/')
    callback(response)

io_loop.add_callback(go_for_it)
io_loop.start()

私がそれを実行すると、メモリフットプリントは時間の経過とともに多かれ少なかれ直線的に増加し続けます。ただし、gen.engineネストを削除すると、次のようになります。

@gen.engine
def go_for_it():
    while True:
        r = yield gen.Task(client.fetch, 'http://localhost:8888/')

メモリ使用量は一定のままです。

Mac OS X と Linux の両方で、さまざまなバージョンの tornado 2 で問題を再現することができました。この問題の原因は何ですか?

4

1 に答える 1

3

objgraph パ​​ッケージの助けを借りて掘り下げると、コードが ExceptionStackContexts をリークしているようです。これらは、関数の例外を処理するために gen.engine によって作成されます。これらはクリアする必要がありますが、明らかにバグが見つかりました。

私の最善の推測は、どこかに参照が残っているということです。

編集 - Tornado チーム (Ben) が修正を発見し、将来のリリースで修正される予定です。 https://github.com/facebook/tornado/commit/bff07405549a6eb173a4cfc9bbc3fc7c6da5cdd7

于 2012-11-16T06:05:19.260 に答える