Twisted + Cyclone + Pypyを使用してPOSTリクエストを処理するとメモリリークが発生しますか?

StackOverflow https://stackoverflow.com//questions/21063842

質問

多くの調査の後、何百ものHTTP POST要求を提供した後に、メモリリークがあります。奇妙な部分は、Pypyを使用するときにのみメモリリークが発生することです。

これはコード例です:

from twisted.internet import reactor
import tornado.ioloop

do_tornado = False
port = 8888

if do_tornado:
    from tornado.web import RequestHandler, Application
else:
    from cyclone.web import RequestHandler, Application

class MainHandler(RequestHandler):
    def get(self):
        self.write("Hello, world")

    def post(self):
        self.write("Hello, world")

if __name__ == "__main__":
    routes = [(r"/", MainHandler)]
    application = Application(routes)

    print port
    if do_tornado:
        application.listen(port)
        tornado.ioloop.IOLoop.instance().start()
    else:
        reactor.listenTCP(port, application)
        reactor.run()
.

ここに要求を生成するために使用しているテストコードです:

from twisted.internet import reactor, defer
from twisted.internet.task import LoopingCall

from twisted.web.client import Agent, HTTPConnectionPool
from twisted.web.iweb import IBodyProducer

from zope.interface import implements

pool = HTTPConnectionPool(reactor, persistent=True)
pool.retryAutomatically = False
pool.maxPersistentPerHost = 10
agent = Agent(reactor, pool=pool)

bid_url = 'http://localhost:8888'

class StringProducer(object):
    implements(IBodyProducer)

    def __init__(self, body):
        self.body = body
        self.length = len(body)

    def startProducing(self, consumer):
        consumer.write(self.body)
        return defer.succeed(None)

    def pauseProducing(self):
        pass

    def stopProducing(self):
        pass


def callback(a):
    pass

def error_callback(error):
    pass

def loop():
    d = agent.request('POST', bid_url, None, StringProducer("Hello, world"))
    #d = agent.request('GET', bid_url)
    d.addCallback(callback).addErrback(error_callback)


def main():
    exchange = LoopingCall(loop)
    exchange.start(0.02)

    #log.startLogging(sys.stdout)
    reactor.run()

main()
.

このコードは、CPythonと竜巻とPYPYで漏洩していないことに注意してください。コードは、ツイストとPYPYを一緒に使用する場合にのみリークし、POSTリクエストを使用する場合に限ります。

漏れを見るためには、何十万もの要求を送る必要があります。

pypy_gc_maxを設定するとき、プロセスは最終的にクラッシュします。

何が起こっているのか?

役に立ちましたか?

解決

リークの原因はBytesIOモジュールです。

Pypyの漏れをシミュレートする方法

from io import BytesIO
while True: a = BytesIO()
.

これが修正です。 https://bitbucket.org/pypy/pypy/commits/40fa4f3a0740e3aac77862fe8a853259c07cb00bする

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top