首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Twisted + Cyclone + PyPy处理POST请求会导致内存泄漏吗?

使用Twisted + Cyclone + PyPy处理POST请求会导致内存泄漏吗?
EN

Stack Overflow用户
提问于 2014-01-11 15:04:22
回答 1查看 746关注 0票数 4

经过大量的调查,我发现在为成千上万的HTTP请求提供服务之后,出现了内存泄漏。奇怪的是,内存泄漏仅在使用PyPy时发生。

下面是一个示例代码:

代码语言:javascript
复制
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()

下面是我用来生成请求的测试代码:

代码语言:javascript
复制
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!只有在同时使用Twisted和Pypy时,以及在使用POST请求时,代码才会泄漏。

要查看漏洞,您必须发送数十万个请求。

注意,当设置PYPY_GC_MAX时,进程最终会崩溃。

到底怎么回事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-30 08:26:03

结果发现泄漏的原因是BytesIO模块。

下面是如何模拟Pypy上的泄漏。

代码语言:javascript
复制
from io import BytesIO
while True: a = BytesIO()

以下是修复方法:https://bitbucket.org/pypy/pypy/commits/40fa4f3a0740e3aac77862fe8a853259c07cb00b

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21063842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档