代码之家  ›  专栏  ›  技术社区  ›  zpoint

使用CurlAsyncHTTPClient的HTTPS请求内存泄漏

  •  2
  • zpoint  · 技术社区  · 7 年前

    我的处理程序文件

    # -*- coding:utf-8 -*-
    import sys
    from tornado import gen, web, httpclient
    
    url = "https://mdetail.tmall.com/templates/pages/desc?id=527485572414"
    
    class SearchHandler(web.RequestHandler):
        @gen.coroutine
        def get(self):
            async_client = httpclient.AsyncHTTPClient()
            print sys.getrefcount(async_client) # The first time less than 10, then always bigger than 200
            req = httpclient.HTTPRequest(url, "GET", headers=headers)
            req_lists = [async_client.fetch(req) for _ in range(200)]
            r = yield req_lists
            print sys.getrefcount(async_client) # always bigger than 200
            # The longer req_lists, the more memory will be consumed, and never decrease
    

    tornado.httpclient.AsyncHTTPClient.configure(client, max_clients=1000)
    

    如果我的客户是 “tornado.curl\u httpclient.CurlAsyncHTTPClient” 然后当我去broswer拜访我的经纪人时, 显示内存增加约6GB,只要进程运行,内存使用量就不会减少

    范围(200) 范围(500) 或者更高,内存使用率会更高

    如果我的诊所是 没有一个 ,内存几乎没有增加

    将出现内存问题

    我该如何解决记忆问题 ?

    Ubuntu 16.10 x64
    python2.7.12
    Tornado 4.5.1
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Vasiliy Faronov    7 年前

    您看到的引用计数是预期的,因为 max_clients=1000 ,Tornado将缓存并重新使用 1000 pycurl.Curl instances ,每个 hold a reference 致客户 _curl_header_callback .你可以用 objgraph.show_backrefs .

    最大客户端数=1000 也就是说,最多并行1000个请求?(我希望它们不是都在同一台服务器上,就像你的例子一样!)

    Curl 实例似乎占用了大量内存。

    $ /usr/bin/time -v python getter.py 
    6
    207
    ^C
    [...]
        Maximum resident set size (kbytes): 4853544
    

    $ LD_LIBRARY_PATH=$PWD/curl-prefix/lib /usr/bin/time -v python getter.py 
    6
    207
    ^C
    [...]
        Maximum resident set size (kbytes): 1016084
    

    如果我在OpenSSL后端使用libcurl,结果会更好:

        Maximum resident set size (kbytes): 275572
    

    还有其他关于GNUTL内存问题的报告: curl issue #1086 .

    max_clients ,尝试使用用OpenSSL后端构建的较新libcurl。