Twisted + Cyclone + Pypyを使用してPOSTリクエストを処理するとメモリリークが発生しますか?
-
26-12-2019 - |
質問
多くの調査の後、何百もの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()
.
これが修正です。
所属していません StackOverflow